package com.apes.fn.scm.retailOrder.service.tc;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.apes.fn.business.carAccident.modle.ClaimWorkOrder;
import com.apes.fn.business.insurance.modle.PolicyInformation;
import com.apes.fn.fico.settleExpense.SettleExpense;
import com.apes.fn.pi.fnCommunal.FnCommunalService;
import com.apes.fn.scm.retailOrder.model.BudgetCut;
import com.apes.fn.scm.retailOrder.model.RetailOrder;
import com.apes.fn.scm.retailOrder.model.RetailOrderItem;
import com.apes.fn.scm.retailOrder.repository.BudgetCutRepository;
import com.apes.fn.scm.retailOrder.service.tc.RptWorkOutputValue.RptWorkOutputValue;
import com.apes.fn.scm.retailOrder.service.tc.RptWorkOutputValue.RptWorkOutputValueRepository;
import com.apes.fn.scm.retailOrder.service.tc.employeeBusinessOutputValue.EmployeeBusinessOutputValue;
import com.apes.fn.scm.retailOrder.service.tc.employeeBusinessOutputValue.EmployeeBusinessOutputValueRepository;
import com.apes.fn.scm.retailOrder.service.tc.tcOutbox.TcOutbox;
import com.apes.fn.scm.retailOrder.service.tc.tcOutbox.TcOutboxBackup;
import com.apes.fn.scm.retailOrder.service.tc.tcOutbox.TcOutboxBackupRepository;
import com.apes.fn.scm.retailOrder.service.tc.tcOutbox.TcOutboxRepository;
import com.apes.fn.scm.saleReport.repository.CostDetailsRepository;
import com.apes.fn.scm.saleReport.repository.TurnoverDetailsRepository;
import com.apes.fn.scm.saleReport.service.SaleReportService;
import com.apes.fn.server.servicePlan.model.ServicePlan;
import com.apes.fn.server.servicePlan.service.ServiceToForeign;
import com.apes.fn.server.transferVehicle.model.InnerPickDeliveryUpCar;
import com.apes.framework.api.DomainService;
import com.apes.framework.api.SpringManager;
import com.apes.framework.jpa.generator.service.SequenceService;
import com.apes.framework.jpa.spec.JpaDsl;
import com.apes.framework.plugin.esb.api.SimpleRequest;
import com.apes.framework.plugin.event.Listener;
import com.apes.framework.util.*;
import com.apes.pi.model.Timestamp;
import com.apes.pi.repository.TimestampRepository;
import com.apes.scm.masterdata.frame.model.Dept;
import com.apes.scm.masterdata.frame.repository.DeptRepository;
import com.apes.scm.masterdata.frame.service.StoreService;
import com.apes.scm.masterdata.party.model.PartyRole;
import com.apes.scm.masterdata.party.repository.PartyRoleRepository;
import com.apes.scm.masterdata.product.model.Brand;
import com.apes.scm.masterdata.product.model.Classify;
import com.apes.scm.masterdata.product.model.Product;
import com.apes.scm.masterdata.product.model.ProductUom;
import com.apes.scm.masterdata.product.repository.ProductRepository;
import com.apes.scm.masterdata.product.repository.ProductUomRepository;
import com.apes.scm.masterdata.product.repository.ServeCategoryRepository;
import com.apes.scm.sal.saleOrder.SaleOrder;
import org.apache.commons.lang.StringUtils;
import org.bson.Document;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.support.TransactionTemplate;

import javax.persistence.EntityManager;
import javax.persistence.Query;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
import java.util.stream.Collectors;

import static com.apes.framework.util.DateUtil.add;
import static com.apes.framework.util.DateUtil.format;

/**
 * 功能：提成计算服务
 *
 * @author linwz
 * @create 2020-07-07 16:56
 */
@Service("tcService")
public class TCService extends DomainService {

    @Autowired
    private ProductRepository productRepository;
    @Autowired
    private ServeCategoryRepository serveCategoryRepository;
    @Autowired
    private PartyRoleRepository partyRoleRepository;
    @Autowired
    private DeptRepository deptRepository;
    @Autowired
    private ProductUomRepository productUomRepository;
    @Autowired
    private TimestampRepository timestampRepository;
    @Autowired
    private BudgetCutRepository budgetCutRepository;
    @Autowired
    private TcOutboxRepository tcOutboxRepository;
    @Autowired
    private TCDao tcDao;
    @Autowired
    private TransactionTemplate transactionTemplate;
    @Autowired
    private TcOutboxBackupRepository tcOutboxBackupRepository;
    @Autowired
    private DistributedLock distributedLock;
    @Autowired
    private MongoTemplate mongoTemplate;

    /**
     * 定时任务生成提成消费报错
     *
     * @param request map
     */
    public synchronized void saveRetailTc(SimpleRequest request) {
        Page<TcOutbox> outboxList = tcOutboxRepository.findByStateAndOutboxDateNotIn(1, new Date(),PageRequest.of(0, 300));
        outboxList.getContent().forEach(this::xsetc);
    }

    /**
     * 定时任务生成提成未消费
     *
     * @param request map
     */
    public synchronized void saveRetailTcByState(SimpleRequest request) {
        Page<TcOutbox> outboxList = tcOutboxRepository.findByStateAndOutboxDateNotIn(0, new Date(),PageRequest.of(0, 100));
        outboxList.getContent().forEach(this::xsetc);
    }

    /**
     * 施工提成跨单报错推送消息至APP
     */
    public Map<Object,Object> retailTcMessage(SimpleRequest request){
        String id = request.get("ID");
        TcOutbox tcOutbox = tcOutboxRepository.getTcMessage(id);
        Map<Object, Object> map = new HashMap<>();
        if(tcOutbox == null){
            map.put("message","");
            return map;
        }
        String substringBetween = StringUtils.substringBetween(tcOutbox.getError(), "跨单:", "明细");
        map.put("message","注意:此配件属于"+substringBetween+"方案的，与该工时搭配施工需对应方案都结算后才可以核算提成! ! !");
        return map;
    }

    /**
     * 生成提成并发死锁重试
     *
     * @param simpleRequest map
     */
    public void retailTcRetry(SimpleRequest simpleRequest) {
        JSONObject request =  new JSONObject();
        JSONArray retailTcRetryArray = tcDao.getRetailTcRetry(request);
        retailTcRetryArray.forEach(it -> {
            JSONObject data = (JSONObject) it;
            try{
                execute(() -> {
                    tcDao.deleteRetailTcRetry(data) ;
                });
            }catch (Exception e){}
            this.invoke("condition.execConditionStrategy", MapUtil.mapper(
                    "ID", data.getString("BILL_ID"),
                    "conditionStrategyId", data.getString("CON_STR_ID")));
        });
    }


    /**
     * 生成提成后推送至App
     *
     * @param request map
     */
    public void pushRetailTcToApp(SimpleRequest request) {
        TcOutboxBackup outbox = request.getO(TcOutboxBackup.class);
        String aggregateType = outbox.getAggregateType();
        JSONObject param = new JSONObject();
        JSONArray result = new JSONArray();
        if (aggregateType.equals("RetailOrder") || aggregateType.equals("SaleOrder") || aggregateType.equals("ClaimWorkOrder")) {
            param.put("RETAIL_ORDER_ID", outbox.getAggregateId());
            result = SpringManager.getBean(TCDao.class).queryXSETCById(param);
        } else if (aggregateType.equals("InnerPickDeliveryUpCar")) {
            param.put("FN_INNER_PICK_DEL_UP_CAR_ID", outbox.getAggregateId());
            result = SpringManager.getBean(TCDao.class).queryKDTCById(param);
        } else if (aggregateType.equals("PolicyInformation")) {
            param.put("ID", outbox.getAggregateId());
            result = SpringManager.getBean(TCDao.class).queryCXTCById(param);
        } else if (aggregateType.equals("SettleExpense")) {
            JSONObject tempJson = JSON.parseObject(outbox.getPayload());
            SettleExpense settleExpense = MapUtil.getO(tempJson, SettleExpense.class);
            param.put("ID", settleExpense.getSource());
            result = SpringManager.getBean(TCDao.class).queryDSXSETCById(param);
        }

        for (int i = 0; i < result.size(); i++) {
            JSONObject jsonObject = result.getJSONObject(i);
            Double MAIN_SALESMAN_TCJE = jsonObject.getDouble("MAIN_SALESMAN_TCJE");
            if (MAIN_SALESMAN_TCJE != 0) {
                String topic = "event:pi.app.synApp";
                Map mainMap = getData(outbox.getAggregateId(), jsonObject);

                if (Objects.nonNull(jsonObject.get("MAIN_MOBILE"))) {   // 主销
                    EventUtil.sendSynEvent(this, topic, mainMap);
                }

                if (jsonObject.get("SUB_MOBILE") != null) { // 辅销
                    Map subMap = getData(outbox.getAggregateId(), jsonObject);
                    subMap.put("money", jsonObject.getString("SUB_SALESMAN_TCJE"));
                    subMap.put("mobile", jsonObject.get("SUB_MOBILE"));
                    EventUtil.sendSynEvent(this, topic, subMap);
                }
            }
        }
    }

    private Map getData(String aggregateId, JSONObject jsonObject){
        Map map = new HashMap();
        map.put("scene", "PushMoney");
        map.put("orderId", aggregateId);
        map.put("method", "v1/push-message/push");
        map.put("title", "提成通知");
        map.put("money", jsonObject.getString("MAIN_SALESMAN_TCJE"));
        map.put("sendAt",  String.valueOf(new Date().getTime()/1000));
        map.put("storeCode", jsonObject.get("DEPT_ID"));
        map.put("mobile", jsonObject.get("MAIN_MOBILE"));
        map.put("main_salesman", jsonObject.get("MAIN_SALESMAN"));
        map.put("sub_salesman", jsonObject.get("SUB_SALESMAN"));
        return map;
    }


    private void backup(TcOutbox event) {
        TcOutboxBackup outboxEventBackup = new TcOutboxBackup();
        ReflectUtil.copyAll(event, outboxEventBackup);
        outboxEventBackup.setTimestamp(LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());
        tcOutboxBackupRepository.saveAndFlush(outboxEventBackup);
    }

    @Autowired
    private TurnoverDetailsRepository turnoverDetailsRepository;
    @Autowired
    private CostDetailsRepository costDetailsRepository;
    @Autowired
    private SaleReportService saleReportService;
    /**
     * 零售单收款后收集待生成提成的数据
     *
     * @param request map
     */
    public void retailTc(SimpleRequest request) {
        RetailOrder saleOrder = request.getO(RetailOrder.class);
        if(saleOrder.getOrderType().equals("paymentUpdate")) return;
        if (turnoverDetailsRepository.findByOrigin(saleOrder.getId()).size() == 0 && costDetailsRepository.findByOrigin(saleOrder.getId()).size() == 0){
            String orderType = saleOrder.getOrderType();
            if(!"DS0".equals(orderType) && !"lossQuotation".equals(orderType) && !"directPay".equals(orderType) && !"noDirectPay".equals(orderType)){
                Map<String, Object> map = MapUtil.mapped(saleOrder);
                map.put("ORDER_TYPE", "retailOrder");
                SimpleRequest simpleRequest = new SimpleRequest();
                simpleRequest.setData(map);
                saleReportService.createSaleReport(simpleRequest);
            }
        }
        if("vouched".equals(saleOrder.getState()) || "done".equals(saleOrder.getState())){
            String payload = JSONObject.toJSONString(MapUtil.mapped(saleOrder));
            List<TcOutbox> tcOutboxList = tcOutboxRepository.findByAggregateIdAndAggregateType(saleOrder.getId(),saleOrder.getInnerBusinessType());
            if (!tcOutboxList.isEmpty()){
                return;
            }
            TcOutbox tcOutbox = new TcOutbox();
            tcOutbox.setAggregateId(saleOrder.getId());
            tcOutbox.setAggregateType(saleOrder.getInnerBusinessType());
            tcOutbox.setTimestamp(LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());
            tcOutbox.setPayload(payload);
            tcOutboxRepository.saveAndFlush(tcOutbox);
        }
    }


    /**
     * 分销单收款后分发调用
     * 条件策略生成各项提成数据
     *
     * @param request map
     */
    public void saleOrderTc(SimpleRequest request) {
        SaleOrder saleOrder = request.getO(SaleOrder.class);
        if (turnoverDetailsRepository.findByOrigin(saleOrder.getId()).size() == 0 && costDetailsRepository.findByOrigin(saleOrder.getId()).size() == 0){
            Map<String, Object> map = MapUtil.mapped(saleOrder);
            map.put("ORDER_TYPE", "saleOrder");
            SimpleRequest simpleRequest = new SimpleRequest();
            simpleRequest.setData(map);
            saleReportService.createSaleReport(simpleRequest);
        }
        String payload = JSONObject.toJSONString(MapUtil.mapped(saleOrder));
        List<TcOutbox> tcOutboxList = tcOutboxRepository.findByAggregateIdAndAggregateType(saleOrder.getId(),saleOrder.getInnerBusinessType());
        if (!tcOutboxList.isEmpty()){
            return;
        }
        TcOutbox tcOutbox = new TcOutbox();
        tcOutbox.setAggregateId(saleOrder.getId());
        tcOutbox.setAggregateType(saleOrder.getInnerBusinessType());
        tcOutbox.setTimestamp(LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());
        tcOutbox.setPayload(payload);
        tcOutboxRepository.saveAndFlush(tcOutbox);
    }

    /**
     * 车险报价单审核后分发调用
     * 条件策略生成各项提成数据
     *
     * @param request map
     */
    public void insuranceOrderTc(SimpleRequest request) {
        PolicyInformation insuranceOrder = request.getO(PolicyInformation.class);
        String payload = JSONObject.toJSONString(MapUtil.mapped(insuranceOrder));
        List<TcOutbox> tcOutboxList = tcOutboxRepository.findByAggregateIdAndAggregateType(insuranceOrder.getId(),"PolicyInformation");
        if (!tcOutboxList.isEmpty()){
            return;
        }
        TcOutbox tcOutbox = new TcOutbox();
        tcOutbox.setAggregateId(insuranceOrder.getId());
        tcOutbox.setAggregateType("PolicyInformation");
        tcOutbox.setTimestamp(LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());
        tcOutbox.setPayload(payload);
        tcOutboxRepository.saveAndFlush(tcOutbox);
    }

    /**
     * 结算费用单提成数据
     * 定损销售额提成
     * @param request map
     */
    public void settleExpenseTc(SimpleRequest request) {
        SettleExpense SettleExpense = request.getO(com.apes.fn.fico.settleExpense.SettleExpense.class);
        String payload = JSONObject.toJSONString(MapUtil.mapped(SettleExpense));
        List<TcOutbox> tcOutboxList = tcOutboxRepository.findByAggregateIdAndAggregateType(SettleExpense.getId(),"SettleExpense");
        if (!tcOutboxList.isEmpty()){
            return;
        }
        TcOutbox tcOutbox = new TcOutbox();
        tcOutbox.setAggregateId(SettleExpense.getId());
        tcOutbox.setAggregateType("SettleExpense");
        tcOutbox.setTimestamp(LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());
        tcOutbox.setPayload(payload);
        tcOutboxRepository.saveAndFlush(tcOutbox);
    }

    /**
     * 服务方案单提成数据
     * 计算销售提成和施工提成
     * @param request map
     */
    public void servicePlanTc(SimpleRequest request) {
        ServicePlan servicePlan = request.getO(ServicePlan.class);
        String payload = JSONObject.toJSONString(MapUtil.mapped(servicePlan));
        List<TcOutbox> tcOutboxList = tcOutboxRepository.findByAggregateIdAndAggregateType(servicePlan.getId(),"ServicePlan");
        if (!tcOutboxList.isEmpty()){
            return;
        }
        TcOutbox tcOutbox = new TcOutbox();
        tcOutbox.setAggregateId(servicePlan.getId());
        tcOutbox.setAggregateType("ServicePlan");
        tcOutbox.setTimestamp(LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());
        tcOutbox.setPayload(payload);
        tcOutboxRepository.saveAndFlush(tcOutbox);
    }

    /**
     * 定损工单 提成数据
     * 代勘提成
     * @param request map
     */
    public void claimWorkOrderTc(SimpleRequest request) {
        ClaimWorkOrder claimWorkOrder = request.getO(ClaimWorkOrder.class);
        String payload = JSONObject.toJSONString(MapUtil.mapped(claimWorkOrder));
        List<TcOutbox> tcOutboxList = tcOutboxRepository.findByAggregateIdAndAggregateType(claimWorkOrder.getId(),"ClaimWorkOrder");
        if (!tcOutboxList.isEmpty()){
            return;
        }
        TcOutbox tcOutbox = new TcOutbox();
        tcOutbox.setAggregateId(claimWorkOrder.getId());
        tcOutbox.setAggregateType("ClaimWorkOrder");
        tcOutbox.setTimestamp(LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());
        tcOutbox.setPayload(payload);
        tcOutboxRepository.saveAndFlush(tcOutbox);
    }

    public void execute(Callback callback) {
        transactionTemplate.execute(status -> {
            try {
                callback.execute();
                return null;
            } catch (Exception e) {
                status.isRollbackOnly();
                throw e;
            }
        });
    }

    @FunctionalInterface
    public interface Callback {
        @Nullable
        void execute();
    }


    /**
     * 销售额提成
     * @param tcOutbox
     */
    public synchronized void xsetc(TcOutbox tcOutbox) {
        final TcOutbox[] outbox = {tcOutbox};
        try {
            execute(() -> {
                String aggregateType = outbox[0].getAggregateType();
                String aggregateId = outbox[0].getAggregateId();
                invokeTC(aggregateType,aggregateId);
                outbox[0].incTimes();
                outbox[0].setState(2);
                outbox[0].setTimestamp(LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());
                backup(outbox[0]);
                tcOutboxRepository.delete(outbox[0]);
            });

        }catch (Exception e) {
            String errorMessage;
            if (e instanceof NullPointerException) {
                errorMessage = e.getClass().getName() + " ：" + Tools.getFirstStackTrace(e);
            } else {
                errorMessage = Tools.getThrowable(e).getMessage();
            }
            execute(() -> {
                outbox[0].incTimes();
                outbox[0].setState(1);
                outbox[0].setError(errorMessage);
                outbox[0].setTimestamp(LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());
                LocalDateTime localDateTime = LocalDateTime.now();
                if (outbox[0].getTimes() > 12) {
                    int time = outbox[0].getTimes()*5;
                    localDateTime = localDateTime.plusMinutes(time);
                } else {
                    localDateTime = localDateTime.plusHours(1);
                }
                Date date = Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
                outbox[0].setOutboxDate(date);
                outbox[0] = tcOutboxRepository.saveAndFlush(outbox[0]);
//                if (outbox[0].getTimes() == 16) {
//                    dingDingService.pushNotifications(dingDingToken.getAccessToken(), "0110483500641146019,01142665076924415363", outbox[0].getAggregateId() + "已消费16次，都错了，赶紧看看！");
//                }
            });


        }
    }

    private void saveLog(TcOutbox outbox,String remark) {
        Map map = MapUtil.mapped(outbox);
        Document document = new Document(map);
        document.put("remark", remark);
        document.put("date", LocalDateTime.now());
        mongoTemplate.getCollection("tcOutbox").insertOne(document);
    }


    /**
     * 毛利额提成
     * @param request
     */
    @Listener(topic = "event:tc.service.mletc")
    public void mletc(SimpleRequest request) {
        RetailOrder saleOrder = request.getO(RetailOrder.class);
        this.invoke("condition.execConditionStrategy", MapUtil.mapper(
                "ID",saleOrder.getId(),
                "conditionStrategyId","TC_MLETC_SK"));
    }





    /**
     * 内协交接车确认收车后生成提成
     * @param request
     */
    public void innerPickDeliveryUpCarCommission(SimpleRequest request) {
        InnerPickDeliveryUpCar innerPickDeliveryUpCar = request.getO(InnerPickDeliveryUpCar.class);
        String payload = JSONObject.toJSONString(MapUtil.mapped(innerPickDeliveryUpCar));
        TcOutbox tcOutbox = new TcOutbox();
        tcOutbox.setAggregateId(innerPickDeliveryUpCar.getId());
        tcOutbox.setAggregateType(innerPickDeliveryUpCar.getInnerBusinessType());
        tcOutbox.setTimestamp(LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());
        tcOutbox.setPayload(payload);
        tcOutboxRepository.saveAndFlush(tcOutbox);

    }

    /**
     * 定时任务,定时获取老系统销售订单收款后代勘提成
     */
    public void oldDKCommission() throws ParseException {
        Date today = new Date();
        Timestamp timestamp = timestampRepository.findOne("fn.res.oldDKCommission");
        String begin = format(DateUtil.parse(timestamp.getTime(), DateUtil.SHOW_DATETIME_FORMAT), DateUtil.SHOW_DATE_FORMAT);
        String end = format(add(today,5,1), DateUtil.SHOW_DATE_FORMAT);
        this.invoke("tc.employeeCommissionService.execDKTCDSWCOLD", MapUtil.mapper(
                "DATE_START", com.apestech.framework.util.DateUtil.strToDate(begin),
                "DATE_END", com.apestech.framework.util.DateUtil.strToDate(end)));
        timestamp.setTime(format(today, DateUtil.SHOW_DATETIME_FORMAT));
        timestampRepository.saveAndFlush(timestamp);
    }

    /**
     * 提成日报 日结
     * @param request
     */
    public void retailTCRBB(SimpleRequest request) {
        Date date = new Date();
        Date date1 = DateUtil.add(date,5,1);
        String today = DateUtil.format(date, DateUtil.SHOW_DATE_FORMAT);
        String tomorrow = DateUtil.format(date1, DateUtil.SHOW_DATE_FORMAT);
        this.invoke("condition.execReport", MapUtil.mapper(
                "TJRQ_STAR", today,
                "TJRQ_END",tomorrow,
                "reportId","TC_RYTCRBB"));

    }

    /**
     * 方案计算单品预估提成
     * 输出预估提成
     * @return
     */
    public Double obtainEstimatedCommission(String PRODUCT_ID,String CLASSIFY_ID,String SERVE_TYPE_ID,String BRAND_ID,
                                            Double PROFIT_AMT,Double SALE_AMT,Double LOCK_PRICE,Double YXSDJ,
                                            String COMPANY_ID,String OPERATION){
        Map map = MapUtil.mapper(
                "PRODUCT_ID",PRODUCT_ID,"CLASSIFY_ID",CLASSIFY_ID,"SERVE_TYPE_ID",SERVE_TYPE_ID,"BRAND_ID",BRAND_ID,
                "COMPANY_ID",COMPANY_ID,"ORDER_TYPE","ServicePlan","SOURCE_BUSINESS_TYPE_NAME","服务方案","OPERATION",OPERATION,"SYS_RQ",new Date(),"conditionStrategyId","TC_YSXSTC_SK",
                "PROFIT_AMT",PROFIT_AMT,"SALE_AMT",SALE_AMT,"DISCOUNT_AMOUNT",0,"NKDK_AMT",0,"LOCK_PRICE",LOCK_PRICE,"SALE_QTY",1,"YXSDJ",YXSDJ,"HBDK_AMT",0,"FXDK_AMT",0,"DSBJ",0
        );
        try {
            Object obj = this.invoke("condition.execConditionStrategy_trans",map);
            JSONObject result = obj == null ? new JSONObject() : new JSONObject(MapUtil.mapped(obj));
            return result.getDoubleValue("TCJE") ; //TCJE为空会返回0
        }catch (Exception e){
            e.printStackTrace();
            return 0.0;
        }
    }

    /**
     * App来源订单预估提成
     * @return
     */
    public JSONArray estimatedCommissionByApp(SimpleRequest request) throws IllegalAccessException, InstantiationException {
        JSONArray jsonArray = request.getJA();
        JSONArray returnArray = new JSONArray();
        for (int i = 0; i < jsonArray.size(); i++) {
            JSONObject jsonObject = jsonArray.getJSONObject(i);
            String PRODUCT_ID = jsonObject.getString("PRODUCT_ID");
            String COMPANY_ID = jsonObject.getString("COMPANY_ID");
            String MDID = jsonObject.getString("MDID");
            String carNumber = jsonObject.getString("CAR_NUMBER");
            Dept dept = deptRepository.findOne(MDID);
            if (dept == null) throw new RuntimeException("未找到对应门店,请检查编码是否正确.");
            Product product = productRepository.findOne(PRODUCT_ID);
            if (product == null) throw new RuntimeException("未找到对应商品,请检查编码是否正确.");
            Classify classify = product.getClassify();
            String CLASSIFY_ID = classify.getId();
            String SERVE_TYPE_ID = serveCategoryRepository.findByProductId(PRODUCT_ID);
            Brand brand = product.getBrand();
            String BRAND_ID = brand.getId();
            double SALE_QTY = jsonObject.getDouble("SALE_QTY");
            double SALE_AMT = jsonObject.getDouble("SALE_AMT");

            PartyRole partyRole = partyRoleRepository.findOne(COMPANY_ID);
            if (!partyRole.getRole().getId().equals("Company")) throw new RuntimeException("传入的公司id不是一个公司,请检查.");
            String OPERATION = partyRole.getParty().getCorporate().getOperation().getDescription();

            ProductUom uom = productUomRepository.findAll(
                    JpaDsl.toCriteriaByEq("uomCategory.id",product.getUom().getUomCategory().getId(),"saleFirst",true)
            ).stream().findFirst().get();
            //平台
            PartyRole platform = SpringManager.getBean(FnCommunalService.class).getPlatform(false,true, dept,product);
            JSONObject resultJsonReback = SpringManager.getBean(ServiceToForeign.class).getXS51(MapUtil.mapper(
                    "uniqueIdentify",product.getId(),
                    "MDID",jsonObject.getString("MDID"),
                    "PLID",product.getClassify().getId(),
                    "SPID",product.getId(),
                    "PZID",product.getBrand().getQuality() == null ? null : product.getBrand().getQuality().getCode(),
                    "HZLXID", null ,
                    "PPID",product.getBrand().getId(),   //品牌找品质
                    "XSZZID",COMPANY_ID,
                    "GSID",COMPANY_ID,
                    "CLFWDJID",null,
                    //"MDLXID",dept.getDeptType().getId(),
                    "FNVIPJBID", null,
                    "FNVIPSFID",null,
                    "CGZZID",platform.getId(),
                    "JLDW",uom.getName(),
                    "YYMS",partyRole.getParty().getCorporate().getOperation().getCode(),
                    "NYYMS",partyRole.getParty().getCorporate().getOperation().getId(),
                    "SYGSID",platform.getId(),
                    "SQID", SpringManager.getBean(StoreService.class).findBusinessCircleByDept(dept).getId(),
                    "XYGSID",partyRole.getId()
            ),true);
            Double LOCK_PRICE =  resultJsonReback.getDouble("floorPrice");//锁价
            Double YXSDJ = 0.0;//锁价
            Double referTax =  resultJsonReback.getDouble("referTax");//参考成本
            Double PROFIT_AMT = referTax;

            Map map = MapUtil.mapper(
                    "PRODUCT_ID",PRODUCT_ID,"CLASSIFY_ID",CLASSIFY_ID,"SERVE_TYPE_ID",SERVE_TYPE_ID,"BRAND_ID",BRAND_ID,
                    "COMPANY_ID",COMPANY_ID,"ORDER_TYPE","APP","SOURCE_BUSINESS_TYPE_NAME","app预算方案","OPERATION",OPERATION,"SYS_RQ",new Date(),"conditionStrategyId","TC_YSXSTC_SK",
                    "PROFIT_AMT",PROFIT_AMT,"SALE_AMT",SALE_AMT,"DISCOUNT_AMOUNT",0,"NKDK_AMT",0,"LOCK_PRICE",LOCK_PRICE,"SALE_QTY",SALE_QTY,"YXSDJ",YXSDJ,"HBDK_AMT",0,"FXDK_AMT",0,"DSBJ",0
            );
            try {
                Object obj = this.invoke("condition.execConditionStrategy",map);
                JSONObject result = new JSONObject(MapUtil.mapped(obj));
                double TCJE = result.getDouble("TCJE") == null ? 0 : result.getDouble("TCJE");
                returnArray.add(obj);
                BudgetCut budgetCut = new BudgetCut();
                budgetCut.setProduct(product);
                budgetCut.setCompany(partyRole);
                budgetCut.setDept(dept);
                budgetCut.setClassify(classify);
                budgetCut.setCarNumber(carNumber);
                budgetCut.setCostAmount(PROFIT_AMT);
                budgetCut.setSALE_AMT(SALE_AMT);
                budgetCut.setSaleQty(SALE_QTY);
                budgetCut.setTCJE(TCJE);
                budgetCut.setSys_break(result.getString("sys_break"));
                budgetCut.setConditionStrategyId(result.getString("conditionStrategyId"));
                budgetCut.setT401(result.getDouble("T401")  == null ? 0 : result.getDouble("T401"));
                budgetCut.setNKDK_AMT(result.getDouble("NKDK_AMT"));
                budgetCut.setEND_DATE(result.getString("END_DATE"));
                budgetCut.setSERVE_TYPE_ID(result.getString("SERVE_TYPE_ID"));
                budgetCut.setFXDK_AMT(result.getDouble("FXDK_AMT"));
                budgetCut.setBRAND_ID(result.getString("BRAND_ID"));
                budgetCut.setYXSDJ(result.getDouble("YXSDJ"));
                budgetCut.setT011(result.getDouble("T011")  == null ? 0 : result.getDouble("T011"));
                budgetCut.setT012(result.getDouble("T012")  == null ? 0 : result.getDouble("T012"));
                budgetCut.setT013(result.getDouble("T013")  == null ? 0 : result.getDouble("T013"));
                budgetCut.setT014(result.getDouble("T014")  == null ? 0 : result.getDouble("T014"));
                budgetCut.setORDER_TYPE(result.getString("ORDER_TYPE"));
                budgetCut.setHBDK_AMT(result.getDouble("HBDK_AMT"));
                budgetCut.setLOCK_PRICE(LOCK_PRICE);
                budgetCut.setSALE_AMT(result.getDouble("SALE_AMT"));
                budgetCut.setASSESSMENT_COST_PRICE(result.getDouble("ASSESSMENT_COST_PRICE") == null ? 0 : result.getDouble("ASSESSMENT_COST_PRICE"));
                budgetCut.setOPERATION(result.getString("OPERATION"));
                budgetCut.setSOURCE_BUSINESS_TYPE_NAME(result.getString("SOURCE_BUSINESS_TYPE_NAME"));
                budgetCut.setT002(result.getDouble("T002")  == null ? 0 : result.getDouble("T002"));
                budgetCut.setT024(result.getDouble("T024")  == null ? 0 : result.getDouble("T024"));
                budgetCut.setDISCOUNT_AMOUNT(result.getDouble("DISCOUNT_AMOUNT"));
                budgetCut.setT201(result.getDouble("T201")  == null ? 0 : result.getDouble("T201"));
                budgetCut.setT021(result.getDouble("T021")  == null ? 0 : result.getDouble("T021"));
                budgetCut.setT023(result.getDouble("T023")  == null ? 0 : result.getDouble("T023"));
                budgetCut.setT022(result.getDouble("T022")  == null ? 0 : result.getDouble("T022"));
                budgetCut.setT001(result.getDouble("T001")  == null ? 0 : result.getDouble("T001"));
                budgetCut.setSysRQ(new Date());
                budgetCutRepository.saveAndFlush(budgetCut);
            }catch (Exception e){
                throw new RuntimeException("计算预估提成失败：" + e.getMessage());
            }

        }


        return returnArray;
    }

    /**
     * 获取人员提成报表数据
     * @param simpleRequest
     * @return
     */
    public JSONArray getRptWorkOutputValue(SimpleRequest simpleRequest){
        JSONArray out_result = null;
        try {
            distributedLock.lock("outbox_fn_tc_RptWorkOutputValue",60000);  //根据当前esb去加锁,锁六秒钟
            out_result = transactionTemplate.execute(status -> {
                try {
                    JSONArray result;
                    Timestamp timestamp = timestampRepository.findOne("fn.res.rptWorkOutputValue");
                    if(timestamp == null || timestamp.getTime() == null) return new JSONArray();
                    JSONObject param = new JSONObject();
                    param.put("ID",timestamp.getTime());
                    result = SpringManager.getBean(TCDao.class).queryTCRYSGTC(param);
                    if(result.size() != 0){
                        String sID = result.getJSONObject(result.size() - 1).getString("ID");
                        timestamp.setTime(sID);
                        timestampRepository.save(timestamp);
                    }
                    return result;
                } catch (Exception e) {
                    status.isRollbackOnly();
                    throw e;
                }
            });
            return out_result;
        }catch (Exception e){
            throw new RuntimeException(e);
        }finally {
            distributedLock.unlock("outbox_fn_tc_RptWorkOutputValue");
        }
    }
    /**
     * 获取接送车提成数据
     * @param simpleRequest
     * @return
     */
    public JSONArray getRptWorkOutputValueJSC(SimpleRequest simpleRequest){
        Timestamp timestamp = timestampRepository.findOne("fn.res.rptWorkOutputValueJSC");
        if(timestamp == null || timestamp.getTime() == null) return new JSONArray();
        JSONObject param = new JSONObject();
        param.put("ID",timestamp.getTime());
        JSONArray result = SpringManager.getBean(TCDao.class).queryTCRYSGTCJSC(param);
        if(result.size() != 0){
            String sID = result.getJSONObject(result.size() - 1).getString("ID");
            timestamp.setTime(sID);
            timestampRepository.save(timestamp);
        }
        return result;
    }
    /**
     * 获取开单提成数据
     * @param simpleRequest
     * @return
     */
    public JSONArray getRptWorkOutputValueKD(SimpleRequest simpleRequest){
        Timestamp timestamp = timestampRepository.findOne("fn.res.rptWorkOutputValueKD");
        if(timestamp == null || timestamp.getTime() == null) return new JSONArray();
        JSONObject param = new JSONObject();
        param.put("ID",timestamp.getTime());
        JSONArray result = SpringManager.getBean(TCDao.class).queryTCRYSGTCKD(param);
        if(result.size() != 0){
            String sID = result.getJSONObject(result.size() - 1).getString("ID");
            timestamp.setTime(sID);
            timestampRepository.save(timestamp);
        }
        return result;
    }

    public void rptWorkOutputValue(SimpleRequest simpleRequest){
        JSONObject jo1 = simpleRequest.getJO();
        String lock1 = "outbox_" + jo1.getString("DEPT_ID") + "_" + jo1.getString("WORKER") + "_" + DateUtil.format(jo1.getDate("CREATE_DATE"),DateUtil.SHOW_DATE_FORMAT)  ;
        //根据日期+部门+员工编码进行加锁
        try {
            distributedLock.lock(lock1,60000);  //根据当前esb去加锁,锁六秒钟
            transactionTemplate.execute(status -> {
                try {
                    JSONObject jo = simpleRequest.getJO();
                    jo.put("DEPT_ID",jo.getString("DEPT_ID"));
                    jo.put("DEPT_NAME",jo.getString("DEPT_NAME"));
                    jo.put("EMPLOYEE_ID",jo.getString("WORKER"));
                    jo.put("EMPLOYEE_NAME",jo.getString("WORKER_NAME"));
                    jo.put("COMPANY_ID",jo.getString("COMPANY_ID"));
                    jo.put("COMPANY_NAME",jo.getString("COMPANY_NAME"));
                    jo.put("TJRQ", DateUtil.dateToDate(jo.getDate("CREATE_DATE"),"yyyyMMdd"));
                    //查询施工产值表
                    List<RptWorkOutputValue> rptWorkOutputValueList= SpringManager.getBean(RptWorkOutputValueRepository.class).findAll(
                            JpaDsl.toCriteriaByEq("tjrq", jo.getDate("TJRQ"),"employeeId",jo.getString("EMPLOYEE_ID"),"deptId",jo.getString("DEPT_ID"))
                    );
                    RptWorkOutputValue rptWorkOutputValue;
                    //判断新增还是更新
                    switch (rptWorkOutputValueList.size()){
                        case 0:
                            rptWorkOutputValue = new RptWorkOutputValue();
                            setBaseInfo(rptWorkOutputValue,jo);
                            break;
                        case 1:
                            rptWorkOutputValue = rptWorkOutputValueList.stream().findFirst().get();
                            break;
                        default:
                            throw new RuntimeException("违反联合主键冲突");
                    }
                    //设置提成
                    setCaculateCommision(rptWorkOutputValue,jo);
                    //设置产值与台次
                    setOutputValue(rptWorkOutputValue,jo);
                    SpringManager.getBean(RptWorkOutputValueRepository.class).saveAndFlush(rptWorkOutputValue);
                    return null;
                } catch (Exception e) {
                    status.isRollbackOnly();
                    throw e;
                }
            });
        }catch (Exception e){
            throw new RuntimeException(e);
        }finally {
            distributedLock.unlock(lock1);
        }
    }
    public void rptWorkOutputValueJSC(SimpleRequest simpleRequest){
        JSONObject jo = simpleRequest.getJO();
        jo.put("DEPT_ID",jo.getString("DISPATCHER_DEPT_ID"));
        jo.put("DEPT_NAME",jo.getString("DISPATCHER_DEPT_NAME"));
        jo.put("EMPLOYEE_ID",jo.getString("JSCR"));
        jo.put("EMPLOYEE_NAME",jo.getString("JSCR_NAME"));
        jo.put("COMPANY_ID",jo.getString("COMPANY_ID"));
        jo.put("COMPANY_NAME",jo.getString("COMPANY_NAME"));
        jo.put("TJRQ", DateUtil.dateToDate(jo.getDate("CREATE_DATE"),"yyyyMMdd"));
        List<RptWorkOutputValue> rptWorkOutputValueList= SpringManager.getBean(RptWorkOutputValueRepository.class).findAll(
                JpaDsl.toCriteriaByEq("tjrq", jo.getDate("TJRQ"),"employeeId",jo.getString("EMPLOYEE_ID"),"deptId",jo.getString("DEPT_ID"))
        );
        RptWorkOutputValue rptWorkOutputValue;
        switch (rptWorkOutputValueList.size()){
            case 0:
                rptWorkOutputValue = new RptWorkOutputValue();
                setBaseInfo(rptWorkOutputValue,jo);
                break;
            case 1:
                rptWorkOutputValue = rptWorkOutputValueList.stream().findFirst().get();
                break;
            default:
                throw new RuntimeException("违反联合主键冲突");
        }
        rptWorkOutputValue.setDeliverAmount(rptWorkOutputValue.getDeliverAmount() + 1);
        rptWorkOutputValue.setDeliverCommision(rptWorkOutputValue.getDeliverCommision() + jo.getDoubleValue("TC_AMT"));
        rptWorkOutputValue.setWorkCommisionAll(jo.getDouble("TC_AMT") + rptWorkOutputValue.getWorkCommisionAll());
        SpringManager.getBean(RptWorkOutputValueRepository.class).saveAndFlush(rptWorkOutputValue);
    }
    public void rptWorkOutputValueKD(SimpleRequest simpleRequest){
        JSONObject jo = simpleRequest.getJO();
        jo.put("DEPT_ID",jo.getString("DEPT_ID"));
        jo.put("DEPT_NAME",jo.getString("DEPT_NAME"));
        jo.put("EMPLOYEE_ID",jo.getString("BILL_MAN"));
        jo.put("EMPLOYEE_NAME",jo.getString("BILL_MAN_NAME"));
        jo.put("COMPANY_ID",jo.getString("COMPANY_ID"));
        jo.put("COMPANY_NAME",jo.getString("COMPANY_NAME"));
        jo.put("TJRQ", DateUtil.dateToDate(jo.getDate("CREATE_DATE"),"yyyyMMdd"));
        List<RptWorkOutputValue> rptWorkOutputValueList= SpringManager.getBean(RptWorkOutputValueRepository.class).findAll(
                JpaDsl.toCriteriaByEq("tjrq", jo.getDate("TJRQ"),"employeeId",jo.getString("EMPLOYEE_ID"),"deptId",jo.getString("DEPT_ID"))
        );
        RptWorkOutputValue rptWorkOutputValue;
        switch (rptWorkOutputValueList.size()){
            case 0:
                rptWorkOutputValue = new RptWorkOutputValue();
                setBaseInfo(rptWorkOutputValue,jo);
                break;
            case 1:
                rptWorkOutputValue = rptWorkOutputValueList.stream().findFirst().get();
                break;
            default:
                throw new RuntimeException("违反联合主键冲突");
        }
        rptWorkOutputValue.setInnerAssistCommision(rptWorkOutputValue.getInnerAssistCommision() + jo.getDoubleValue("TC_AMT"));
        rptWorkOutputValue.setWorkCommisionAll(jo.getDouble("TC_AMT") + rptWorkOutputValue.getWorkCommisionAll());
        SpringManager.getBean(RptWorkOutputValueRepository.class).saveAndFlush(rptWorkOutputValue);
    }
    /**
     * 设置提成
     * @param rptWorkOutputValue
     * @param jo
     */
    private void setCaculateCommision(RptWorkOutputValue rptWorkOutputValue, JSONObject jo) {
        switch (jo.getString("SERVE_TYPE_ID")){
            case "001":
                rptWorkOutputValue.setWashCommision(jo.getDouble("TC_AMT") + rptWorkOutputValue.getWashCommision());
                break;
            case "002":
                rptWorkOutputValue.setCosmetologyCommision(jo.getDouble("TC_AMT") + rptWorkOutputValue.getCosmetologyCommision());
                break;
            case "003":
                rptWorkOutputValue.setMaintenanceCommision(jo.getDouble("TC_AMT") + rptWorkOutputValue.getMaintenanceCommision());
                break;
            case "004":
                rptWorkOutputValue.setRepairCommision(jo.getDouble("TC_AMT") + rptWorkOutputValue.getRepairCommision());
                break;
            case "005":
                rptWorkOutputValue.setReconfigurationCommsion(jo.getDouble("TC_AMT") + rptWorkOutputValue.getReconfigurationCommsion());
                break;
            case "006":
                rptWorkOutputValue.setDelicateCommision(jo.getDouble("TC_AMT") + rptWorkOutputValue.getDelicateCommision());
                break;
            case "007": //钣金喷漆
                if(jo.getString("CLASSIFY_ID").startsWith("S0106")){ //喷漆，剩下钣喷
                    rptWorkOutputValue.setSprayPaintCommision(jo.getDouble("TC_AMT") + rptWorkOutputValue.getSprayPaintCommision());
                }else{ //钣喷
                    rptWorkOutputValue.setMetalplateCommision(jo.getDouble("TC_AMT") + rptWorkOutputValue.getMetalplateCommision());
                }
                break;
            case "008":
                rptWorkOutputValue.setRescueCommision(jo.getDouble("TC_AMT") + rptWorkOutputValue.getRescueCommision());
                break;
            case "009":
                rptWorkOutputValue.setDailyArticleCommision(jo.getDouble("TC_AMT") + rptWorkOutputValue.getDailyArticleCommision());
                break;
            case "021":
                rptWorkOutputValue.setTyreCommision(jo.getDouble("TC_AMT") + rptWorkOutputValue.getTyreCommision());
                break;
            case "020":
                rptWorkOutputValue.setInformationServiceCommision(jo.getDouble("TC_AMT") + rptWorkOutputValue.getInformationServiceCommision());
                break;
            case "024":
                rptWorkOutputValue.setTechnicalDetectionCommision(jo.getDouble("TC_AMT") + rptWorkOutputValue.getTechnicalDetectionCommision());
                break;
            default:
        }
        rptWorkOutputValue.setWorkCommisionAll(jo.getDouble("TC_AMT") + rptWorkOutputValue.getWorkCommisionAll());
    }
    /**
     * 统计过程
     * @param rptWorkOutputValue
     * @param jo
     */
    private void setOutputValue(RptWorkOutputValue rptWorkOutputValue, JSONObject jo) {
        switch (jo.getString("SERVE_TYPE_ID")){
            case "001":
                rptWorkOutputValue.setWashAmount((jo.getDoubleValue("SALE_AMT") < 0 ? - jo.getDoubleValue("WASH_AMOUNT") : jo.getDoubleValue("WASH_AMOUNT")) + rptWorkOutputValue.getWashAmount());
                rptWorkOutputValue.setWashOutputValue(jo.getDouble("PORTIONSUM") + rptWorkOutputValue.getWashOutputValue());
                rptWorkOutputValue.setWorkOutputValueAll(jo.getDouble("PORTIONSUM") + rptWorkOutputValue.getWorkOutputValueAll());
                break;
            case "002":
                rptWorkOutputValue.setCosmetologyOutputValue(jo.getDouble("PORTIONSUM") + rptWorkOutputValue.getCosmetologyOutputValue());
                rptWorkOutputValue.setWorkOutputValueAll(jo.getDouble("PORTIONSUM") + rptWorkOutputValue.getWorkOutputValueAll());
                break;
            case "003":
                rptWorkOutputValue.setMaintenanceOutputValue(jo.getDouble("PORTIONSUM") + rptWorkOutputValue.getMaintenanceOutputValue());
                rptWorkOutputValue.setWorkOutputValueAll(jo.getDouble("PORTIONSUM") + rptWorkOutputValue.getWorkOutputValueAll());
                break;
            case "004":
                rptWorkOutputValue.setRepairOutputValue(jo.getDouble("PORTIONSUM") + rptWorkOutputValue.getRepairOutputValue());
                rptWorkOutputValue.setWorkOutputValueAll(jo.getDouble("PORTIONSUM") + rptWorkOutputValue.getWorkOutputValueAll());
                break;
            case "005":
                rptWorkOutputValue.setReconfigurationOutputValue(jo.getDouble("PORTIONSUM") + rptWorkOutputValue.getReconfigurationOutputValue());
                rptWorkOutputValue.setWorkOutputValueAll(jo.getDouble("PORTIONSUM") + rptWorkOutputValue.getWorkOutputValueAll());
                break;
            case "006":
                rptWorkOutputValue.setDelicateOutputValue(jo.getDouble("PORTIONSUM") + rptWorkOutputValue.getDelicateOutputValue());
                rptWorkOutputValue.setWorkOutputValueAll(jo.getDouble("PORTIONSUM") + rptWorkOutputValue.getWorkOutputValueAll());
                break;
            case "007": //钣金喷漆
                if(jo.getString("CLASSIFY_ID").startsWith("S0106")){ //喷漆，剩下钣喷
                    double dFS = jo.getDoubleValue("SALE_AMT") < 0 ?
                            -jo.getDoubleValue("SALE_QTY") * jo.getDoubleValue("SPECIFICATIONS") : jo.getDoubleValue("SALE_QTY") * jo.getDoubleValue("SPECIFICATIONS");
                    if(1 == jo.getDoubleValue("PROCESS")){
                        rptWorkOutputValue.setPaintDeal(dFS + rptWorkOutputValue.getPaintDeal());
                    }else if(2 == jo.getDoubleValue("PROCESS")){
                        rptWorkOutputValue.setBottomGrinding(dFS + rptWorkOutputValue.getBottomGrinding());
                    }else if(3 == jo.getDoubleValue("PROCESS")){
                        rptWorkOutputValue.setSprayPaint(dFS + rptWorkOutputValue.getSprayPaint());
                    }else{
                        rptWorkOutputValue.setRefinement(dFS + rptWorkOutputValue.getRefinement());
                    }
                }else{ //钣喷
                    //针对冲红部分： TC_AMT ，SUMTC，SALE_AMT 都是负数，所以算出来也是反向的。
                    double bpCZ = jo.getDoubleValue("SUMTC") == 0 ? 0 : jo.getDoubleValue("TC_AMT") / jo.getDoubleValue("SUMTC") * jo.getDoubleValue("SALE_AMT");
                    rptWorkOutputValue.setMetalplateOutputValue(rptWorkOutputValue.getMetalplateOutputValue() + bpCZ);
                    rptWorkOutputValue.setWorkOutputValueAll(bpCZ + rptWorkOutputValue.getWorkOutputValueAll());
                }
                break;
            case "008":
                rptWorkOutputValue.setRescueOutputValue(jo.getDouble("PORTIONSUM") + rptWorkOutputValue.getRescueOutputValue());
                rptWorkOutputValue.setWorkOutputValueAll(jo.getDouble("PORTIONSUM") + rptWorkOutputValue.getWorkOutputValueAll());
                break;
            case "009":
                rptWorkOutputValue.setDailyArticleOutputValue(jo.getDouble("PORTIONSUM") + rptWorkOutputValue.getDailyArticleOutputValue());
                rptWorkOutputValue.setWorkOutputValueAll(jo.getDouble("PORTIONSUM") + rptWorkOutputValue.getWorkOutputValueAll());
                break;
            case "021":
                rptWorkOutputValue.setTyreOutputValue(jo.getDouble("PORTIONSUM") + rptWorkOutputValue.getTyreOutputValue());
                rptWorkOutputValue.setWorkOutputValueAll(jo.getDouble("PORTIONSUM") + rptWorkOutputValue.getWorkOutputValueAll());
                break;
            case "020":
                rptWorkOutputValue.setInformationServiceOutputValue(jo.getDouble("PORTIONSUM") + rptWorkOutputValue.getInformationServiceOutputValue());
                rptWorkOutputValue.setWorkOutputValueAll(jo.getDouble("PORTIONSUM") + rptWorkOutputValue.getWorkOutputValueAll());
                break;
            case "024":
                rptWorkOutputValue.setTechnicalDetectionOutputValue(jo.getDouble("PORTIONSUM") + rptWorkOutputValue.getTechnicalDetectionOutputValue());
                rptWorkOutputValue.setWorkOutputValueAll(jo.getDouble("PORTIONSUM") + rptWorkOutputValue.getWorkOutputValueAll());
                break;
            default:
        }
    }
    /**
     * 基础信息
     * @param rptWorkOutputValue
     * @param jo
     */
    private void setBaseInfo(RptWorkOutputValue rptWorkOutputValue, JSONObject jo) {
        rptWorkOutputValue.setId(SpringManager.getBean(SequenceService.class).getId(RptWorkOutputValue.CONST_TABLE_NAME));
        rptWorkOutputValue.setTjrq(jo.getDate("TJRQ"));
        rptWorkOutputValue.setDeptId(jo.getString("DEPT_ID"));
        rptWorkOutputValue.setDeptName(jo.getString("DEPT_NAME"));
        rptWorkOutputValue.setEmployeeId(jo.getString("EMPLOYEE_ID"));
        rptWorkOutputValue.setEmployeeName(jo.getString("EMPLOYEE_NAME"));
        rptWorkOutputValue.setCompanyId(jo.getString("COMPANY_ID"));
        rptWorkOutputValue.setCompanyName(jo.getString("COMPANY_NAME"));
    }

    /**
     * 提供给计算二手车检测提成
     * @param jo
     */
    public void inspectorCommissionBySubmit(JSONObject jo){
        jo.put("TJRQ", DateUtil.dateToDate(jo.getDate("TJRQ"),"yyyyMMdd"));
        List<RptWorkOutputValue> rptWorkOutputValueList= SpringManager.getBean(RptWorkOutputValueRepository.class).findAll(
                JpaDsl.toCriteriaByEq("tjrq", jo.getDate("TJRQ"),"employeeId",jo.getString("EMPLOYEE_ID"),"deptId",jo.getString("DEPT_ID"))
        );
        RptWorkOutputValue rptWorkOutputValue;
        switch (rptWorkOutputValueList.size()){
            case 0:
                rptWorkOutputValue = new RptWorkOutputValue();
                setBaseInfo(rptWorkOutputValue,jo);
                break;
            case 1:
                rptWorkOutputValue = rptWorkOutputValueList.stream().findFirst().get();
                break;
            default:
                throw new RuntimeException("违反联合主键冲突");
        }
        rptWorkOutputValue.setSecondHandCommision(rptWorkOutputValue.getSecondHandCommision() + jo.getDoubleValue("secondHandCommision"));
        SpringManager.getBean(RptWorkOutputValueRepository.class).saveAndFlush(rptWorkOutputValue);
    }

    /**
     * 处理每一条明细报表中的值
     * @param simpleRequest
     */
    public void empBusinessOutputValue(SimpleRequest simpleRequest){
        JSONObject jo = simpleRequest.getJO();
        List<EmployeeBusinessOutputValue> employeeBusinessOutputValueList = SpringManager.getBean(EmployeeBusinessOutputValueRepository.class).findAll(
                JpaDsl.toCriteriaByEq("tjrq", jo.getDate("TJRQ"),"partyRoleId",jo.getString("EMPLOYEE_ID"),"deptId",jo.getString("DEPT_ID"))
        );
        EmployeeBusinessOutputValue employeeBusinessOutputValue = null;
        switch (employeeBusinessOutputValueList.size()){
            case 0:
                employeeBusinessOutputValue = new EmployeeBusinessOutputValue();
                setBaseInfoEmp(employeeBusinessOutputValue,jo);
                setCaculateCommisionEmp(employeeBusinessOutputValue,jo);
                break;
            case 1:
                employeeBusinessOutputValue = employeeBusinessOutputValueList.stream().findFirst().get();
                setCaculateCommisionEmp(employeeBusinessOutputValue,jo);
                break;
            default:
                throw new RuntimeException("违反联合主键冲突");
        }
        SpringManager.getBean(EmployeeBusinessOutputValueRepository.class).saveAndFlush(employeeBusinessOutputValue);
    }


    /**
     * 基础信息
     * @param employeeBusinessOutputValue
     * @param jo
     */
    private void setBaseInfoEmp(EmployeeBusinessOutputValue employeeBusinessOutputValue, JSONObject jo) {
        employeeBusinessOutputValue.setTjrq(jo.getDate("TJRQ"));
        employeeBusinessOutputValue.setDeptId(jo.getString("DEPT_ID"));
        employeeBusinessOutputValue.setDeptName(jo.getString("DEPT_NAME"));
        employeeBusinessOutputValue.setPartyRoleId(jo.getString("EMPLOYEE_ID"));
        employeeBusinessOutputValue.setPartyRoleName(jo.getString("EMPLOYEE_NAME"));
        employeeBusinessOutputValue.setCompanyId(jo.getString("COMPANY_ID"));
        employeeBusinessOutputValue.setCompanyName(jo.getString("COMPANY_NAME"));
    }


    /**
     * 统计过程
     * @param employeeBusinessOutputValue
     * @param jo
     */
    private void setCaculateCommisionEmp(EmployeeBusinessOutputValue employeeBusinessOutputValue, JSONObject jo) {
        switch (jo.getString("ORDER_CLASSIFY")){
            case "NKTC":
                employeeBusinessOutputValue.setNKXS(jo.getDouble("SALE_AMT") + employeeBusinessOutputValue.getNKXS());
                employeeBusinessOutputValue.setNKXSTC(jo.getDouble("TCJE") + employeeBusinessOutputValue.getNKXSTC());
                break;
            case "DSXS":
                employeeBusinessOutputValue.setDSJE((jo.getDouble("LOSS_QUOTATION_AMT") + employeeBusinessOutputValue.getDSJE()));
                employeeBusinessOutputValue.setJCJSF((jo.getDouble("SALE_AMT") + employeeBusinessOutputValue.getDSJE()));
                employeeBusinessOutputValue.setJCJSFTC(jo.getDouble("TCJE") + employeeBusinessOutputValue.getJCJSFTC());
                break;
            case "CXTC":
                employeeBusinessOutputValue.setNetPremium((jo.getDouble("NET_PREMIUM") + employeeBusinessOutputValue.getNetPremium()));
                employeeBusinessOutputValue.setFnCommission((jo.getDouble("FN_COMMISSION") + employeeBusinessOutputValue.getFnCommission()));
                employeeBusinessOutputValue.setCXJYE((jo.getDouble("CXJYE") + employeeBusinessOutputValue.getCXJYE()));
                employeeBusinessOutputValue.setNetPremiumTc(jo.getDouble("TCJE") + employeeBusinessOutputValue.getNetPremiumTc());
                break;
            case "XSTC":
                switch (jo.getString("SERVE_TYPE_ID")){
                    case "001":
                        employeeBusinessOutputValue.setXCXS(jo.getDouble("SALE_AMT") + employeeBusinessOutputValue.getXCXS());
                        employeeBusinessOutputValue.setXCXSTC(jo.getDouble("TCJE") + employeeBusinessOutputValue.getXCXSTC());
                        break;
                    case "002":
                        employeeBusinessOutputValue.setMRXS(jo.getDouble("SALE_AMT") + employeeBusinessOutputValue.getMRXS());
                        employeeBusinessOutputValue.setMRXSTC(jo.getDouble("TCJE") + employeeBusinessOutputValue.getMRXSTC());
                        break;
                    case "003":
                        employeeBusinessOutputValue.setBYXS(jo.getDouble("SALE_AMT") + employeeBusinessOutputValue.getBYXS());
                        employeeBusinessOutputValue.setBYXSTC(jo.getDouble("TCJE") + employeeBusinessOutputValue.getBYXSTC());
                        break;
                    case "004":
                        employeeBusinessOutputValue.setWXXS(jo.getDouble("SALE_AMT") + employeeBusinessOutputValue.getWXXS());
                        employeeBusinessOutputValue.setWXXSTC(jo.getDouble("TCJE") + employeeBusinessOutputValue.getWXXSTC());
                        break;
                    case "005":
                        employeeBusinessOutputValue.setGZXS(jo.getDouble("SALE_AMT") + employeeBusinessOutputValue.getGZXS());
                        employeeBusinessOutputValue.setGZXSTC(jo.getDouble("TCJE") + employeeBusinessOutputValue.getGZXSTC());
                        break;
                    case "006":
                        employeeBusinessOutputValue.setJPXS(jo.getDouble("SALE_AMT") + employeeBusinessOutputValue.getJPXS());
                        employeeBusinessOutputValue.setJPXSTC(jo.getDouble("TCJE") + employeeBusinessOutputValue.getJPXSTC());
                        break;
                    case "007": //钣金喷漆
                        employeeBusinessOutputValue.setBPXS(jo.getDouble("SALE_AMT") + employeeBusinessOutputValue.getBPXS());
                        employeeBusinessOutputValue.setBPXSTC(jo.getDouble("TCJE") + employeeBusinessOutputValue.getBPXSTC());
                        break;
                    case "008":
                        employeeBusinessOutputValue.setJYXS(jo.getDouble("SALE_AMT") + employeeBusinessOutputValue.getJYXS());
                        employeeBusinessOutputValue.setJYXSTC(jo.getDouble("TCJE") + employeeBusinessOutputValue.getJYXSTC());
                        break;
                    case "009":
                        employeeBusinessOutputValue.setSHYPXS(jo.getDouble("SALE_AMT") + employeeBusinessOutputValue.getSHYPXS());
                        employeeBusinessOutputValue.setSHYPXSTC(jo.getDouble("TCJE") + employeeBusinessOutputValue.getSHYPXSTC());
                        break;
                    case "020":
                        employeeBusinessOutputValue.setXXFWXS(jo.getDouble("SALE_AMT") + employeeBusinessOutputValue.getXXFWXS());
                        employeeBusinessOutputValue.setXXFWXSTC(jo.getDouble("TCJE") + employeeBusinessOutputValue.getXXFWXSTC());
                        break;
                    case "021":
                        employeeBusinessOutputValue.setLTXS(jo.getDouble("SALE_AMT") + employeeBusinessOutputValue.getLTXS());
                        employeeBusinessOutputValue.setLTXSTC(jo.getDouble("TCJE") + employeeBusinessOutputValue.getLTXSTC());
                        break;
                    case "024":
                        employeeBusinessOutputValue.setJSJCXS(jo.getDouble("SALE_AMT") + employeeBusinessOutputValue.getJSJCXS());
                        employeeBusinessOutputValue.setJSJCXSTC(jo.getDouble("TCJE") + employeeBusinessOutputValue.getJSJCXSTC());
                        break;
                    case "010":
                        employeeBusinessOutputValue.setDIYNKXS(jo.getDouble("SALE_AMT") + employeeBusinessOutputValue.getDIYNKXS());
                        employeeBusinessOutputValue.setDIYNKXSTC(jo.getDouble("TCJE") + employeeBusinessOutputValue.getDIYNKXSTC());
                        break;
                }

            default:
        }
    }

    /**
     * 获取人员年卡提成报表数据
     * @param simpleRequest
     * @return
     */
    public JSONArray getEmpBusinessOutputValueNK(SimpleRequest simpleRequest){
        String interfaceId = "fn.res.empBusinessOutputValueNK";
        Timestamp timestamp = timestampRepository.findOne(interfaceId);
        // 获取 上次更新 时间
        if (timestamp == null) {
            timestamp = new Timestamp();
            timestamp.setId(interfaceId);
            timestamp.setType("timestamp");
            timestamp.setTime("0");
            timestampRepository.save(timestamp);
            return new JSONArray();
        } else {
            JSONObject param = new JSONObject();
            param.put("ID",timestamp.getTime());
            JSONArray result = SpringManager.getBean(TCDao.class).queryTCNKTC(param);
            if(result.size() != 0){
                String sID = result.getJSONObject(result.size() - 1).getString("ID");
                timestamp.setTime(sID);
                timestampRepository.save(timestamp);
            }
            return result;
        }
    }

    /**
     * 获取人员销售提成报表数据
     * @param simpleRequest
     * @return
     */
    public JSONArray getEmpBusinessOutputValue(SimpleRequest simpleRequest){
        String interfaceId = "fn.res.empBusinessOutputValue";
        Timestamp timestamp = timestampRepository.findOne(interfaceId);
        // 获取 上次更新 时间
        if (timestamp == null) {
            timestamp = new Timestamp();
            timestamp.setId(interfaceId);
            timestamp.setType("timestamp");
            timestamp.setTime("0");
            timestampRepository.save(timestamp);
            return new JSONArray();
        } else {
            JSONObject param = new JSONObject();
            param.put("ID",timestamp.getTime());
            JSONArray result = SpringManager.getBean(TCDao.class).queryTCXSTC(param);
            if(result.size() != 0){
                String sID = result.getJSONObject(result.size() - 1).getString("ID");
                timestamp.setTime(sID);
                timestampRepository.save(timestamp);
            }
            return result;
        }
    }

    /**
     * 获取人员定损销售提成报表数据
     * @param simpleRequest
     * @return
     */
    public JSONArray getEmpBusinessOutputValueDS(SimpleRequest simpleRequest){
        String interfaceId = "fn.res.empBusinessOutputValueDS";
        Timestamp timestamp = timestampRepository.findOne(interfaceId);
        // 获取 上次更新 时间
        if (timestamp == null) {
            timestamp = new Timestamp();
            timestamp.setId(interfaceId);
            timestamp.setType("timestamp");
            timestamp.setTime("0");
            timestampRepository.save(timestamp);
            return new JSONArray();
        } else {
            JSONObject param = new JSONObject();
            param.put("ID",timestamp.getTime());
            JSONArray result = SpringManager.getBean(TCDao.class).queryTCDSXSETC(param);
            if(result.size() != 0){
                String sID = result.getJSONObject(result.size() - 1).getString("ID");
                timestamp.setTime(sID);
                timestampRepository.save(timestamp);
            }
            return result;
        }
    }

    /**
     * 获取人员车险销售提成报表数据
     * @param simpleRequest
     * @return
     */
    public JSONArray getEmpBusinessOutputValueCX(SimpleRequest simpleRequest){
        String interfaceId = "fn.res.empBusinessOutputValueCX";
        Timestamp timestamp = timestampRepository.findOne(interfaceId);
        // 获取 上次更新 时间
        if (timestamp == null) {
            timestamp = new Timestamp();
            timestamp.setId(interfaceId);
            timestamp.setType("timestamp");
            timestamp.setTime("0");
            timestampRepository.save(timestamp);
            return new JSONArray();
        } else {
            JSONObject param = new JSONObject();
            param.put("ID",timestamp.getTime());
            JSONArray result = SpringManager.getBean(TCDao.class).queryTCCXTC(param);
            if(result.size() != 0){
                String sID = result.getJSONObject(result.size() - 1).getString("ID");
                timestamp.setTime(sID);
                timestampRepository.save(timestamp);
            }
            return result;
        }
    }

    /**
     * 提供给计算二手车提成
     * @param jo
     */
    public void inCommissionBySubmitToEmp(JSONObject jo){
        jo.put("TJRQ", DateUtil.dateToDate(jo.getDate("TJRQ"),"yyyyMMdd"));
        List<EmployeeBusinessOutputValue> employeeBusinessOutputValueList = SpringManager.getBean(EmployeeBusinessOutputValueRepository.class).findAll(
                JpaDsl.toCriteriaByEq("tjrq", jo.getDate("TJRQ"),"partyRoleId",jo.getString("EMPLOYEE_ID"),"deptId",jo.getString("DEPT_ID"))
        );
        EmployeeBusinessOutputValue employeeBusinessOutputValue;
        switch (employeeBusinessOutputValueList.size()){
            case 0:
                employeeBusinessOutputValue = new EmployeeBusinessOutputValue();
                setBaseInfoEmp(employeeBusinessOutputValue,jo);
                break;
            case 1:
                employeeBusinessOutputValue = employeeBusinessOutputValueList.stream().findFirst().get();
                break;
            default:
                throw new RuntimeException("违反联合主键冲突");
        }
        employeeBusinessOutputValue.setUsedCarFinalPrice(employeeBusinessOutputValue.getUsedCarFinalPrice() + jo.getDoubleValue("USED_CAR_FINAL_PRICE"));
        employeeBusinessOutputValue.setUsedCarPrice(employeeBusinessOutputValue.getUsedCarPrice() + jo.getDoubleValue("USED_CAR_PRICE"));
        employeeBusinessOutputValue.setUsedCarFinalPriceTc(employeeBusinessOutputValue.getUsedCarFinalPriceTc() + jo.getDoubleValue("USED_CAR_FINAL_PRICE_TC"));
        SpringManager.getBean(EmployeeBusinessOutputValueRepository.class).saveAndFlush(employeeBusinessOutputValue);
    }

    // 生成提成后 普通洗车销售 写入 产值表
    public void getEmpBusinessOutputValuePTXC(SimpleRequest request) {
        RetailOrder retailOrder = request.getO(RetailOrder.class);
        List<RetailOrderItem> retailOrderItemList = retailOrder.getSaleItems().stream().filter(retailOrderItem ->
                retailOrderItem.getProduct().getId().equals("000001579") || retailOrderItem.getProduct().getId().equals("0000001585")).collect(Collectors.toList());
        retailOrderItemList.forEach(retailOrderItem -> {
            JSONObject jo = new JSONObject();
            jo.put("TJRQ", retailOrder.getDateDone());
            jo.put("EMPLOYEE_ID", retailOrderItem.getMainSalesman().getId());
            jo.put("EMPLOYEE_NAME", retailOrderItem.getMainSalesman().getName());
            jo.put("DEPT_ID", retailOrder.getDept().getId());
            jo.put("DEPT_NAME", retailOrder.getDept().getName());
            jo.put("COMPANY_ID", retailOrder.getCompany().getId());
            jo.put("COMPANY_NAME", retailOrder.getCompany().getId());
            List<EmployeeBusinessOutputValue> employeeBusinessOutputValueList = SpringManager.getBean(EmployeeBusinessOutputValueRepository.class).findAll(
                    JpaDsl.toCriteriaByEq("tjrq", jo.getDate("TJRQ"), "partyRoleId", jo.getString("EMPLOYEE_ID"), "deptId", jo.getString("DEPT_ID"))
            );
            EmployeeBusinessOutputValue employeeBusinessOutputValue;
            switch (employeeBusinessOutputValueList.size()) {
                case 0:
                    employeeBusinessOutputValue = new EmployeeBusinessOutputValue();
                    setBaseInfoEmp(employeeBusinessOutputValue, jo);
                    break;
                case 1:
                    employeeBusinessOutputValue = employeeBusinessOutputValueList.stream().findFirst().get();
                    break;
                default:
                    throw new RuntimeException("违反联合主键冲突");
            }
            employeeBusinessOutputValue.setPTXCXS(employeeBusinessOutputValue.getPTXCXS() + retailOrderItem.getPriceTotal());
            SpringManager.getBean(EmployeeBusinessOutputValueRepository.class).saveAndFlush(employeeBusinessOutputValue);
        });
    }
    /**
     * 获取人员提成
     * @param simpleRequest
     * @return
     */
    public JSONObject getPersonalPercentage(SimpleRequest simpleRequest){
        JSONObject request = simpleRequest.getJO();
        JSONObject result = new JSONObject();
        //获取月份
        String yearMonth = DateUtil.format("yyyyMM");
        request.put("TJRQ", yearMonth);
        JSONArray arrayMonth= tcDao.queryRYTCForMonth(request);
        //如果没有月提成则直接返回
        result.put("monthPercentage",0);
        result.put("salePercentage", 0);
        result.put("constructionPercentage",0);
        if(arrayMonth.size() == 0)
            return result;
        else
            result.put("monthPercentage", arrayMonth.getJSONObject(0).getDoubleValue("TC_TOTAL"));
        request.put("REQUEST_DATE", new Date());
        JSONArray arrayDay = tcDao.queryRYTCForDay(request);
        if (arrayDay.size() >0) {
            JSONObject dayObject = arrayDay.getJSONObject(0);
            result.put("salePercentage",dayObject.getDoubleValue("XSTC"));
            result.put("constructionPercentage",dayObject.getDoubleValue("SGTC"));
        }
        return result;
    }


    /**
     * 获取人员提成详情
     * @param simpleRequest
     * @return
     */
    public JSONObject getPersonalPercentageDetails(SimpleRequest simpleRequest){
        JSONObject request = simpleRequest.getJO();
        request.put("REQUEST_DATE", request.getDate("REQUEST_DATE"));
        JSONObject result = new JSONObject();
        //获取月份
        String yearMonth = DateUtil.format(request.getDate("REQUEST_DATE"),"yyyyMM");
        request.put("TJRQ", yearMonth);
        //本月累计提成
        JSONArray arrayMonth= tcDao.queryRYTCForMonth(request);
        if(arrayMonth.size() > 0){
            JSONObject objectMonth = arrayMonth.getJSONObject(0);
            result.put("monthPercentage", MapUtil.mapper(
                 "totalPercentage",objectMonth.getDoubleValue("TC_TOTAL"),
                        "salePercentage",objectMonth.getDoubleValue("XSTC"),
                        "constructionPercentage",objectMonth.getDoubleValue("SGTC")
            ));
        }else {
            result.put("monthPercentage", MapUtil.mapper(
                    "totalPercentage",0,
                    "salePercentage",0,
                    "constructionPercentage",0
            ));
        }
        //每日提成数据
        JSONArray arrayDay = tcDao.queryRYTCForDay(request);
        if (arrayDay.size() >0) {
            JSONObject dayObject = arrayDay.getJSONObject(0);
            result.put("dayPercentage", MapUtil.mapper(
                    "totalPercentage",dayObject.getDoubleValue("TC_TOTAL"),
                    "salePercentage",dayObject.getDoubleValue("XSTC"),
                    "constructionPercentage",dayObject.getDoubleValue("SGTC")
            ));
        }else {
            result.put("dayPercentage", MapUtil.mapper(
                    "totalPercentage",0,
                    "salePercentage",0,
                    "constructionPercentage",0
            ));
        }
        //营业提成明细
        JSONObject tradePercentageDetail = new JSONObject();
        JSONArray percentageDetail = getTradePercentageDetail(request);
        if (percentageDetail.size() >0) {
            tradePercentageDetail.put("title","营业提成明细");
            tradePercentageDetail.put("percentageDetail", percentageDetail);
            result.put("tradePercentageDetail",tradePercentageDetail);
        }
        //施工提成明细
        JSONObject constructionPercentageDetail = new JSONObject();
        JSONArray constructionDetail = getConstructionPercentageDetail(request);
        if (constructionDetail.size() >0) {
            constructionPercentageDetail.put("title", "施工提成明细");
            constructionPercentageDetail.put("percentageDetail", constructionDetail);
            result.put("constructionPercentageDetail", constructionPercentageDetail);
        }
        return result;
    }

    /**
     * 获取人员营业提成明细
     * @param
     * @return
     */
    private JSONArray getTradePercentageDetail(JSONObject param){
        JSONArray resultArray = new JSONArray();
        //查询销售提成
        getSalePercentage(param, resultArray,"1");
        //查询年卡提成
        getYearCardPercentage(param,resultArray,"1");
        //查询接案介绍费提成
        getIntroduceFeePercentage(param,resultArray,"1");
        //查询车险销售提成
        getInsurancePercentage(param,resultArray,"1");
        //查询接送车提成
        getGetCarPercentage(param,resultArray,"1");
        //查询开单提成
        getBillingPercentage(param, resultArray,"1");
        //查询二手车提成
        return resultArray;
    }

    /**
     * 获取人员施工提成明细
     * @param
     * @return
     */
    private JSONArray getConstructionPercentageDetail(JSONObject param){
        JSONArray resultArray = new JSONArray();
        getConstructionPercentage(param,resultArray,"1");
        return resultArray;
    }

    private void getSalePercentage(JSONObject param, JSONArray resultArray,String type) {
        JSONArray arrayDay;
        if (Objects.equals("1",type)) arrayDay= tcDao.querySalePercentage(param);
        else arrayDay= tcDao.querySalePercentageForMonth(param);
        if (arrayDay.size() == 0) return;
        //按照销售订单分组, 计算每个订单总提成
        Map<String, List<Object>> map = arrayDay.stream().collect(Collectors.groupingBy(
                item -> {
                    JSONObject object = (JSONObject) item;
                    return object.getString("ORDER_NUMBER");
                }
        ));
        //组装所需数据
        map.forEach((k,v) ->{
            JSONObject object = (JSONObject) v.get(0);
            double percentage = 0;
            JSONObject data = packagePercentage(object,"销售提成");
            percentage = v.stream().mapToDouble(item -> {
                return  ((JSONObject)item).getDoubleValue("TCJE");
            }).sum();
            data.put("PERCENTAGE", Arith.round(percentage,2));
            data.put("ITEM", v);
            resultArray.add(data);
        });
    }

    private void getInsurancePercentage(JSONObject param, JSONArray resultArray,String type) {
        JSONArray arrayDay;
        if (Objects.equals("1",type)) {
            arrayDay= tcDao.queryCXTCForDay(param);
        } else {
            arrayDay= tcDao.queryCXTCForMonth(param);
        }
        if (arrayDay.isEmpty()) return;

        //按照销售订单分组, 计算每个订单总提成
        arrayDay.stream().map(item -> (JSONObject) item).forEach(object -> {
            JSONObject data = packagePercentage(object, "车险提成");
            data.put("PERCENTAGE", object.getDoubleValue("TCJE"));
            resultArray.add(data);
        });
    }

    private void getYearCardPercentage(JSONObject param, JSONArray resultArray,String type) {
        JSONArray arrayDay;
        if (Objects.equals("1",type))arrayDay= tcDao.queryNKTCForDay(param);
        else arrayDay= tcDao.queryNKTCForMonth(param);
        if (arrayDay.size() == 0) return;
        //按照销售订单分组, 计算每个订单总提成
        arrayDay.stream().map(item -> (JSONObject) item).forEach(object -> {
            JSONObject data = new JSONObject();
            data.put("ORDER_NUMBER", object.getString("ORDER_NUMBER"));
            data.put("CREATE_DATE", object.getString("TJRQ"));
            data.put("TYPE","年卡提成" );
            data.put("PERCENTAGE", object.getDoubleValue("TCJE"));
            resultArray.add(data);
        });
    }

    private void getIntroduceFeePercentage(JSONObject param, JSONArray resultArray,String type) {
        JSONArray arrayDay;
        if (Objects.equals("1",type))arrayDay= tcDao.queryJSFTCForDay(param);
        else arrayDay= tcDao.queryJSFTCForMonth(param);
        if (arrayDay.size() == 0) return;
        //按照销售订单分组, 计算每个订单总提成
        arrayDay.stream().map(item -> (JSONObject) item).forEach(object -> {
            JSONObject data = packagePercentage(object, "接案介绍费提成");
            data.put("PERCENTAGE", object.getDoubleValue("TCJE"));
            resultArray.add(data);
        });
    }

    private void getGetCarPercentage(JSONObject param, JSONArray resultArray,String type) {
        JSONArray arrayDay;
        if (Objects.equals("1",type))arrayDay= tcDao.queryJSCTCForDay(param);
        else arrayDay= tcDao.queryJSCTCForMonth(param);
        if (arrayDay.size() == 0) return;
        //按照销售订单分组, 计算每个订单总提成
        arrayDay.stream().map(item -> (JSONObject) item).forEach(object -> {
            JSONObject data = packagePercentage(object, "接送车提成");
            data.put("PERCENTAGE", object.getDoubleValue("TCJE"));
            resultArray.add(data);
        });
    }

    private void getBillingPercentage(JSONObject param, JSONArray resultArray,String type) {
        JSONArray arrayDay;
        if (Objects.equals("1",type))arrayDay= tcDao.queryKDTCForDay(param);
        else arrayDay= tcDao.queryKDTCForMonth(param);
        if (arrayDay.size() == 0) return;
        //按照销售订单分组, 计算每个订单总提成
        arrayDay.stream().map(item -> (JSONObject) item).forEach(object -> {
            JSONObject data = packagePercentage(object, "开单提成");
            data.put("PERCENTAGE", object.getDoubleValue("TCJE"));
            resultArray.add(data);
        });
    }

    //封装所需要得提成信息
    private JSONObject packagePercentage(JSONObject object,String type) {
        JSONObject data = new JSONObject();
        data.put("ORDER_NUMBER", object.getString("ORDER_NUMBER"));
        data.put("PLATE_LICENSE", object.getString("PLATE_LICENSE"));
        data.put("LABEL_NAME", object.getString("LABEL_NAME"));
        data.put("MODEL_NAME", object.getString("MODEL_NAME"));
        data.put("CREATE_DATE", object.getString("TJRQ"));
        data.put("SALESMAN_NAME", object.getString("SALESMAN_NAME"));
        data.put("TYPE",type );
        return data;
    }


    /**
     * app获取门店人员提成数据
     * @param simpleRequest
     * @return
     */
    public JSONObject getDeptPercentage(SimpleRequest simpleRequest){
        JSONObject request = simpleRequest.getJO();
        request.put("REQUEST_DATE", request.getDate("REQUEST_DATE"));
        String queryType = "1";   //默认查选每日数据 requestType (1:查询每日数据, 2: 查询每月数据)
        if (request.containsKey("queryType")) queryType = request.getString("queryType");
        JSONObject result = new JSONObject();
        //根据查询类型分别调用不同的方法
        JSONArray percentageArray;
        if (Objects.equals(queryType,"1"))
            percentageArray = tcDao.queryMDTCForDay(request);
        else {
            //获取月份
            String yearMonth = DateUtil.format(request.getDate("REQUEST_DATE"),"yyyyMM");
            request.put("TJRQ", yearMonth);
            percentageArray = tcDao.queryMDTCForMonth(request);
        }
        //本月累计提成
        if(percentageArray.size() > 0){
            JSONObject objectMonth = percentageArray.getJSONObject(0);
            result.put("totalPercentage", objectMonth.getDoubleValue("TC_TOTAL"));
            result.put("salePercentage", objectMonth.getDoubleValue("XSTC"));
            result.put("constructionPercentage", objectMonth.getDoubleValue("SGTC"));
        }else {
            result.put("totalPercentage", 0);
            result.put("salePercentage",0);
            result.put( "constructionPercentage",0);
        }
        //员工明细
        JSONObject employeePercentageDetail = new JSONObject();
        JSONArray percentageDetail =getDeptPercentageDetail(request,queryType,result);
        if (percentageDetail.size() >0) {
            employeePercentageDetail.put("title","员工明细");
            employeePercentageDetail.put("percentageDetail", percentageDetail);
            result.put("employeePercentageDetail",employeePercentageDetail);
        }
        return result;
    }

    /**
     * 统计门店人员提成数据
     * @param queryType 查询类型
     * @param deptCommission 门店总提成对象
     * @return
     */
    private JSONArray getDeptPercentageDetail(JSONObject param,String queryType,JSONObject deptCommission) {
        //根据查询类型分别调用不同的方法
        JSONArray percentageArray;
        if (Objects.equals(queryType,"1"))
            percentageArray = tcDao.queryDeptPercentageWithDay(param);
        else percentageArray = tcDao.queryDeptPercentageWithMonth(param);
        if (percentageArray.size() > 0) {
            percentageArray.forEach(
                    item -> {
                        JSONObject data = (JSONObject) item;
                        double ratio = 0;
                        if (data.getDoubleValue("TC_TOTAL") != 0) {
                            ratio = Arith.div( data.getDoubleValue("TC_TOTAL"),deptCommission.getDoubleValue("totalPercentage"), 4);
                            ratio = Arith.mul(ratio, 100); //百分比
                        }
                        data.put("ratio", ratio + "%");
                    }
            );
        }
        return percentageArray;

    }

    //得到个人施工提成
    private void getConstructionPercentage(JSONObject param, JSONArray resultArray,String type) {
        JSONArray arrayDay;
        // 提成类型(1:营业提成,2,施工提成)
        if (Objects.equals("1",type)){
            arrayDay= tcDao.queryConstructionPercentage(param);
        } else {
            arrayDay= tcDao.queryConstructionPercentageForMonth(param);
        }
        if (arrayDay.size() == 0) return;
        //按照销售订单分组, 计算每个订单总提成
        Map<String, List<Object>> map = arrayDay.stream().collect(Collectors.groupingBy(
                item -> {
                    JSONObject object = (JSONObject) item;
                    return object.getString("ORDER_NUMBER");
                }
        ));
        //组装所需数据
        map.forEach((k,v) ->{
            JSONObject object = (JSONObject) v.get(0);
            double percentage;
            JSONObject data = packagePercentage(object,"施工提成");
            percentage = v.stream().mapToDouble(item -> ((JSONObject)item).getDoubleValue("TCJE")).sum();
            data.put("PERCENTAGE", Arith.round(percentage,2));
            data.put("ITEM", v);
            resultArray.add(data);
        });
    }

    /**
     * 获取人员月营业提成明细
     * @param
     * @return
     */
    public JSONArray getTradePercentageDetailForMonth(SimpleRequest simpleRequest){
        JSONObject request = simpleRequest.getJO();
        request.put("REQUEST_DATE", request.getDate("REQUEST_DATE"));
        String percentageType = "1";   //提成类型(1:营业提成,2,施工提成)
        if (request.containsKey("PERCENTAGE_TYPE")) percentageType = request.getString("PERCENTAGE_TYPE");
        //获取月份
        String yearMonth = DateUtil.format(request.getDate("REQUEST_DATE"),"yyyyMM");
        request.put("TJRQ", yearMonth);
        JSONArray resultArray = new JSONArray();
        JSONArray array = new JSONArray();
        if (Objects.equals("1",percentageType)) {
            //查询销售提成
            getSalePercentage(request, array,"2");
            //查询年卡提成
            getYearCardPercentage(request,array,"2");
            //查询接案介绍费提成
            getIntroduceFeePercentage(request,array,"2");
            //查询车险销售提成
            getInsurancePercentage(request,array,"2");
            //查询接送车提成
            getGetCarPercentage(request,array,"2");
            //查询开单提成
            getBillingPercentage(request, array,"2");
        } else getConstructionPercentage(request, array,"2");
        if (array.size() >0) {
            //按照日期进行分组
            Map<String, List<Object>> map = array.stream().collect(Collectors.groupingBy(
                    item -> {
                        JSONObject object = (JSONObject) item;
                        return object.getString("CREATE_DATE");
                    }
            ));
            map.forEach((k,v) -> {
                JSONObject data = new JSONObject();
                double percentage = v.stream().mapToDouble(item -> ((JSONObject)item).getDoubleValue("PERCENTAGE")).sum();
                data.put("order",v.size());
                data.put("date",k);
                data.put("percentage",percentage);
                data.put("item", v);
                resultArray.add(data);
            });
        }else {
            return array;
        }
        return resultArray;
    }

    /**
     * 获取人员产值
     * @return
     */
    private JSONObject getPersonOutputValue(SimpleRequest simpleRequest){
        JSONObject request = simpleRequest.getJO();
        JSONObject result = new JSONObject();
        //获取月份
        String yearMonth = DateUtil.format(request.getDate("REQUEST_DATE"),"yyyyMM");
        request.put("TJRQ", yearMonth);
        //获取人员营业产值
        JSONArray arrayYYCZMonth= tcDao.queryRYYYCZForMonth(request);
        //获取人员施工产值
        JSONArray arrayGSCZMonth= tcDao.queryRYSGCZForMonth(request);
        if (arrayYYCZMonth.size() >0) {
            JSONObject dayObject = arrayYYCZMonth.getJSONObject(0);
            Double FWYJ = dayObject.getDouble("FWYJ");
            JSONObject item = tcDao.queryRYYYCZItemForMonth(request).getJSONObject(0);
            JSONArray jsonArray = new JSONArray();
            if (FWYJ != null && FWYJ != 0) {
                item.forEach((k,v) ->{
                    double ratio;
                    JSONObject date = new JSONObject();
                    JSONArray itemArray = new JSONArray();
                    ratio = Arith.div(Double.valueOf(v.toString()),FWYJ, 4);
                    ratio = Arith.mul(ratio, 100); //百分比
                    date.put("ratio",ratio + "%");
                    date.put("amount",v);
                    date.put("title",k);
                    date.put("ITEM",itemArray);
                    jsonArray.add(date);
                });
            }
            dayObject.put("saleOutputValueItem",jsonArray);
            result.put("saleOutputValue",dayObject);
        }
        if (arrayGSCZMonth.size() >0) {
            JSONObject dayObject1 = arrayGSCZMonth.getJSONObject(0);
            Double FWSG = dayObject1.getDouble("FWSG");
            JSONObject SGItem = tcDao.queryRYSGCZItemForMonth(request).getJSONObject(0);
            JSONArray jsonArray = new JSONArray();
            if (FWSG != null && FWSG != 0) {
                SGItem.forEach((k,v) ->{
                    double ratio;
                    JSONObject date = new JSONObject();
                    JSONArray itemArray = new JSONArray();

                    ratio = Arith.div(Double.valueOf(v.toString()) , FWSG , 4);
                    ratio = Arith.mul(ratio, 100); //百分比
                    date.put("ratio",ratio + "%");
                    date.put("amount",v);
                    date.put("title",k);
                    date.put("ITEM",itemArray);
                    if (k.equals("洗车")){
                        JSONObject wash = new JSONObject();
                        wash.put("label","台次");
                        wash.put("value",dayObject1.get("WASH_AMOUNT"));
                        date.put("ITEM",itemArray.add(wash));
                    }
                    jsonArray.add(date);
                });
            }
            dayObject1.put("constructionOutputValueItem",jsonArray);
            result.put("constructionOutputValue",dayObject1);
        }
        return result;
    }


    /**
     * 获取门店人员产值
     * @return
     */
    private JSONObject getDeptPersonOutputValue(SimpleRequest simpleRequest){
        JSONObject request = simpleRequest.getJO();
        JSONObject result = new JSONObject();
        //获取月份
        String yearMonth = DateUtil.format(request.getDate("REQUEST_DATE"),"yyyyMM");
        request.put("TJRQ", yearMonth);
        //获取人员营业产值
        JSONArray arrayYYCZMonth= tcDao.queryDeptRYCZForMonth(request);
        //获取人员施工产值
        JSONArray arrayGSCZMonth= tcDao.queryDeptRYSGCZForMonth(request);
        if (arrayYYCZMonth.size() >0) {
            JSONObject dayObject = arrayYYCZMonth.getJSONObject(0);
            JSONArray item = tcDao.queryDeptRYYYCZItemForMonth(request);
            item.forEach(it ->{
                JSONObject data = (JSONObject) it;
                double ratio = 0;
                if (data.getDoubleValue("YYCZ") != 0) {
                    ratio = Arith.div( data.getDoubleValue("YYCZ"),dayObject.getDoubleValue("YYCZ"), 4);
                    ratio = Arith.mul(ratio, 100); //百分比
                }
                data.put("ratio", ratio + "%");
                data.put("title", data.get("PARTY_ROLE_NAME"));
                data.put("amount", data.get("YYCZ") );
                data.remove("PARTY_ROLE_NAME");
                data.remove("YYCZ");
                JSONArray jsonArray = new JSONArray();
                data.forEach((k,v) ->{
                    if (!(k.equals("ratio") || k.equals("title") || k.equals("amount"))){
                        JSONObject wash = new JSONObject();
                        wash.put("label",k);
                        wash.put("value",v);
                        jsonArray.add(wash);

                    }
                });
                data.remove("年卡");
                data.remove("服务");
                data.remove("定损");
                data.remove("车险");
                data.remove("二手车");
                data.put("ITEM", jsonArray );

            });
            dayObject.put("saleOutputValueItem",item);
            result.put("saleOutputValue",dayObject);
        }
        if (arrayGSCZMonth.size() >0) {
            JSONObject dayObject1 = arrayGSCZMonth.getJSONObject(0);
            JSONArray SGItem = tcDao.queryDeptRYSGCZItemForMonth(request);
            SGItem.forEach(it ->{
                JSONObject data = (JSONObject) it;
                double ratio = 0;
                if (data.getDoubleValue("SGCZ") != 0) {
                    ratio = Arith.div( data.getDoubleValue("SGCZ"),dayObject1.getDoubleValue("SGCZ"), 4);
                    ratio = Arith.mul(ratio, 100); //百分比
                }
                data.put("ratio", ratio + "%");
                data.put("title", data.get("EMPLOYEE_NAME"));
                data.put("amount", data.get("SGCZ") );
                data.remove("EMPLOYEE_NAME");
                data.remove("SGCZ");
                JSONArray jsonArray = new JSONArray();
                data.forEach((k,v) ->{
                    if (!(k.equals("ratio") || k.equals("title") || k.equals("amount"))){
                        JSONObject wash = new JSONObject();
                        wash.put("label",k);
                        wash.put("value",v);
                        jsonArray.add(wash);

                    }
                });
                data.remove("服务施工");
                data.remove("洗车台次");
                data.remove("接送车台次");
                data.remove("喷漆副数");
                data.put("ITEM", jsonArray );
            });
            dayObject1.put("constructionOutputValueItem",SGItem);
            result.put("constructionOutputValue",dayObject1);
        }
        return result;
    }


    /**
     * 获取人员预估提成明细
     * @return
     */
    public JSONArray getPersonalEstimatedCommission(SimpleRequest simpleRequest){
        JSONObject request = simpleRequest.getJO();
        JSONArray result = new JSONArray();
        if(!request.containsKey("PERSON") || StringUtils.isEmpty(request.getString("PERSON")))
            throw new RuntimeException("获取人员预估提成,人员编码不能为空!!!");
        JSONArray array = tcDao.getPersonalEstimatedCommissionDetail(request);
        if (array.size() == 0) return result;
        //按照日期进行分组
        Map<String, List<Object>> map = array.stream().collect(Collectors.groupingBy(
                item -> {
                    JSONObject object = (JSONObject) item;
                    return object.getString("ID");
                }
        ));
        map.forEach((k,v) -> {
            JSONObject data = new JSONObject();
            JSONObject object = (JSONObject) v.get(0);
            double commission = v.stream().mapToDouble(item -> ((JSONObject)item).getDoubleValue("COMMISSION")).sum();
            double balance_amount = object.getDoubleValue("BALANCE_AMOUNT");
            //计算占比 提成/付款金额
            double percentage =commission ==0 ? 0 : Arith.div(balance_amount,commission,4);
            percentage = Arith.round(percentage * 100, 2);

            data.put("order_number",k);
            data.put("state",object.getString("STATE"));
            data.put("date",object.getString("CREATE_DATE"));
            data.put("sup_salesman",object.getString("SUP_SALESMAN"));
            data.put("main_salesman",object.getString("MAIN_SALESMAN"));
            data.put("car_license",object.getString("CAR_LICENSE"));
            data.put("car_brand",object.getString("CAR_BRAND"));
            data.put("car_model",object.getString("CAR_MODEL"));
            data.put("payment_amount",balance_amount);
            data.put("percentage",percentage);
            data.put("commission", Arith.round(commission,2));
            data.put("item", v);
            result.add(data);
        });
        return result;
    }

    public com.apestech.framework.json.JSONObject queryXstc(SimpleRequest request){
        com.apestech.framework.json.JSONObject json = new com.apestech.framework.json.JSONObject();
        try {
            String body = request.getData().toString();
            json = com.apestech.framework.json.JSON.toJSON(body);
            com.apestech.framework.json.JSONArray jsonarray = new com.apestech.framework.json.JSONArray();
            if (!(body.indexOf("MAIN_SALESMAN_SUB")!=-1 || body.indexOf("PERSON_ID")!=-1  || body.indexOf("SALESMAN")!=-1 || body.indexOf("BILL_MAN")!=-1
                    || body.indexOf("WORKER")!=-1 || body.indexOf("SALESMAN_ID")!=-1 || body.indexOf("SERVICE_PLAN_MAN")!=-1  || body.indexOf("GET_CAR_UID")!=-1)){
                Map map = MapUtil.mapper("field", "DEPT_ID", "type", "pt_dept","purpose", "pp_search", "exp","ROLE_DEPT_ID", "nativeQuery","true");
                jsonarray.add(map);

                json.put("nativeAuth", jsonarray);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return json;
    }


    public com.apestech.framework.json.JSONObject queryJsctc(SimpleRequest request){
        com.apestech.framework.json.JSONObject json = new com.apestech.framework.json.JSONObject();
        try {
            String body = request.getData().toString();
            json = com.apestech.framework.json.JSON.toJSON(body);
            com.apestech.framework.json.JSONArray jsonarray = new com.apestech.framework.json.JSONArray();

            if(body.indexOf("JSCR")==-1){
                Map map = MapUtil.mapper("field", "DEPT_ID_MD", "type", "pt_dept","purpose", "pp_search", "exp","ROLE_DEPT_ID", "nativeQuery","true");
                Map map2 = MapUtil.mapper("field", "DEPT_ID_JD", "type", "pt_dept","purpose", "pp_search", "exp","ROLE_DEPT_ID", "nativeQuery","true");
                jsonarray.add(map);
                jsonarray.add(map2);

                json.put("nativeAuth", jsonarray);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return json;
    }

    public com.apestech.framework.json.JSONObject queryXstcY(SimpleRequest request){
        com.apestech.framework.json.JSONObject json = new com.apestech.framework.json.JSONObject();
        try {
            String body = request.getData().toString();
            json = com.apestech.framework.json.JSON.toJSON(body);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return json;
    }


    /**
     * 定时任务,销售日月报表
     */
    public void tcEMPBUSOUTPUTVALUE() throws Exception {

        Date currentTime = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

        String sDate = sdf.format(currentTime);
        Date datenew = sdf.parse(sDate);


        EntityManager entityManager = SpringManager.getBean(EntityManager.class);
        Query query = entityManager.createNativeQuery("{call SUM_TC_EMP_BUS_OUTPUT_VALUE(?)}")
                .setParameter(1, datenew);
        int count = query.executeUpdate();
        System.out.println("----------------:" + count);
    }


    /**
     * app获取人员排名
     * @return
     */
    public JSONArray getEmpBusValueRank(SimpleRequest simpleRequest){
        JSONObject request = simpleRequest.getJO();
        JSONArray result = new JSONArray();
        if(!request.containsKey("DEPT_ID") || StringUtils.isEmpty(request.getString("DEPT_ID")))
            throw new RuntimeException("获取预估排名,门店编码不能为空!!!");
        if(!request.containsKey("TJRQ") || StringUtils.isEmpty(request.getString("TJRQ")))
            throw new RuntimeException("获取预估排名,日期不能为空!!!");
        //查看人员预估产值排名
        JSONArray czRankArray = tcDao.getPersonCZRank(request);
        //查看人员预估提成排名
        JSONArray tcRankArray = tcDao.getPersonTCRank(request);
        //查看门店营业额排名
        if (czRankArray.size()>0){
            result.add(czRankArray.get(0));
        }
        if (tcRankArray.size()>0){
            result.add(tcRankArray.get(0));
        }

        return result;
    }


    /**
     * app获取产值/提成统计（日）
     * @return
     */
    public JSONArray getDeptBusValue(SimpleRequest simpleRequest){
        JSONObject request = simpleRequest.getJO();

        if(!request.containsKey("DEPT_ID") || StringUtils.isEmpty(request.getString("DEPT_ID")))
            throw new RuntimeException("获取预估产值/提成,门店编码不能为空!!!");
        if(!request.containsKey("TJRQ") || StringUtils.isEmpty(request.getString("TJRQ")))
            throw new RuntimeException("获取预估产值/提成,日期不能为空!!!");
        //查看人员预估产值排名
        JSONArray DeptBusValue = tcDao.getDeptBusValueRank(request);
        return DeptBusValue;
    }

    /**
     * app获取产值/提成统计（月）
     * @return
     */
    public JSONArray getDeptBusValueMon(SimpleRequest simpleRequest){
        JSONObject request = simpleRequest.getJO();

        if(!request.containsKey("DEPT_ID") || StringUtils.isEmpty(request.getString("DEPT_ID")))
            throw new RuntimeException("获取预估产值/提成,门店编码不能为空!!!");
        if(!request.containsKey("TJRQ") || StringUtils.isEmpty(request.getString("TJRQ")))
            throw new RuntimeException("获取预估产值/提成,日期不能为空!!!");
        String StrTjrq = request.getString("TJRQ");
        Date tjrq = DateUtil.parse(StrTjrq);
        Date last = DateUtil.getMonthLastDay(tjrq);
        Date first = DateUtil.getMonthFirstDay(tjrq);
        request.put("TJRQ",DateUtil.format(first,DateUtil.SHOW_DATE_FORMAT));
        request.put("TJRQEND",DateUtil.format(last,DateUtil.SHOW_DATE_FORMAT));
        //查看人员预估产值排名
        JSONArray DeptBusValue = tcDao.getDeptBusValueMon(request);
        return DeptBusValue;
    }
    /**
     * app获取产值/提成统计（时间区间）
     * @return
     */
    public JSONArray getDeptBusValueWeek(SimpleRequest simpleRequest){
        JSONObject request = simpleRequest.getJO();

        if(!request.containsKey("DEPT_ID") || StringUtils.isEmpty(request.getString("DEPT_ID")))
            throw new RuntimeException("获取预估产值/提成,门店编码不能为空!!!");
        if(!request.containsKey("TJRQ_S") || StringUtils.isEmpty(request.getString("TJRQ_S")))
            throw new RuntimeException("获取预估产值/提成,日期不能为空!!!");
        if(!request.containsKey("TJRQ_E") || StringUtils.isEmpty(request.getString("TJRQ_E")))
            throw new RuntimeException("获取预估产值/提成,日期不能为空!!!");
        String StrTjrq_s = request.getString("TJRQ_S");
        String StrTjrq_e = request.getString("TJRQ_E");
        Date tjrq_s = DateUtil.parse(StrTjrq_s);
        Date tjrq_e = DateUtil.parse(StrTjrq_e);
//        Date last = DateUtil.getMonthLastDay(tjrq);
//        Date first = DateUtil.getMonthFirstDay(tjrq);
        request.put("TJRQ",DateUtil.format(tjrq_s,DateUtil.SHOW_DATE_FORMAT));
        request.put("TJRQEND",DateUtil.format(tjrq_e,DateUtil.SHOW_DATE_FORMAT));
        //查看人员预估产值排名
        JSONArray DeptBusValue = tcDao.getDeptBusValueMon(request);
        return DeptBusValue;
    }


    /**
     * app获取人员产值排名（日）
     * @return
     */
    public JSONArray getEmpValueRank(SimpleRequest simpleRequest){
        JSONObject request = simpleRequest.getJO();

        if(!request.containsKey("DEPT_ID") || StringUtils.isEmpty(request.getString("DEPT_ID")))
            throw new RuntimeException("获取预估产值/提成,门店编码不能为空!!!");
        if(!request.containsKey("TJRQ") || StringUtils.isEmpty(request.getString("TJRQ")))
            throw new RuntimeException("获取预估产值/提成,日期不能为空!!!");
        //查看人员预估产值排名
        JSONArray empBusValueRank = tcDao.getEmpValueRank(request);
        empBusValueRank.forEach(it ->{
            JSONObject data = (JSONObject) it;
            double ratio = 0;
            if (data.getDoubleValue("CZ") != 0) {
                ratio = Arith.div( data.getDoubleValue("CZ"),data.getDoubleValue("SUMTOTAL"), 4);
                ratio = Arith.mul(ratio, 100); //百分比
            }
            data.put("ratio", ratio + "%");
        });
        return empBusValueRank;
    }

    /**
     * app获取人员产值排名（月）
     * @return
     */
    public JSONArray getEmpValueRankMon(SimpleRequest simpleRequest){
        JSONObject request = simpleRequest.getJO();

        if(!request.containsKey("DEPT_ID") || StringUtils.isEmpty(request.getString("DEPT_ID")))
            throw new RuntimeException("获取预估产值/提成,门店编码不能为空!!!");
        if(!request.containsKey("TJRQ") || StringUtils.isEmpty(request.getString("TJRQ")))
            throw new RuntimeException("获取预估产值/提成,日期不能为空!!!");
        String StrTjrq = request.getString("TJRQ");
        Date tjrq = DateUtil.parse(StrTjrq);
        Date last = DateUtil.getMonthLastDay(tjrq);
        Date first = DateUtil.getMonthFirstDay(tjrq);
        request.put("TJRQ",DateUtil.format(first,DateUtil.SHOW_DATE_FORMAT));
        request.put("TJRQEND",DateUtil.format(last,DateUtil.SHOW_DATE_FORMAT));
        //查看人员预估产值排名
        JSONArray empBusValueRankMon = tcDao.getEmpValueRankMon(request);
        empBusValueRankMon.forEach(it ->{
            JSONObject data = (JSONObject) it;
            double ratio = 0;
            if (data.getDoubleValue("CZ") != 0) {
                ratio = Arith.div( data.getDoubleValue("CZ"),data.getDoubleValue("SUMTOTAL"), 4);
                ratio = Arith.mul(ratio, 100); //百分比
            }
            data.put("ratio", ratio + "%");
        });
        return empBusValueRankMon;
    }

    /**
     * app获取人员产值排名（周）
     * @return
     */
    public JSONArray getEmpValueRankWeek(SimpleRequest simpleRequest){
        JSONObject request = simpleRequest.getJO();

        if(!request.containsKey("DEPT_ID") || StringUtils.isEmpty(request.getString("DEPT_ID")))
            throw new RuntimeException("获取预估产值/提成,门店编码不能为空!!!");
        if(!request.containsKey("TJRQ") || StringUtils.isEmpty(request.getString("TJRQ")))
            throw new RuntimeException("获取预估产值/提成,开始日期不能为空!!!");
        if(!request.containsKey("TJRQEND") || StringUtils.isEmpty(request.getString("TJRQEND")))
            throw new RuntimeException("获取预估产值/提成,结束日期不能为空!!!");
        String StrTjrq = request.getString("TJRQ");
        String StrTjrqE = request.getString("TJRQEND");
        Date tjrq = DateUtil.parse(StrTjrq);
        Date tjrqE = DateUtil.parse(StrTjrqE);
        request.put("TJRQ",DateUtil.format(tjrq,DateUtil.SHOW_DATE_FORMAT));
        request.put("TJRQEND",DateUtil.format(tjrqE,DateUtil.SHOW_DATE_FORMAT));
        //查看人员预估产值排名
        JSONArray empBusValueRankMon = tcDao.getEmpValueRankMon(request);
        empBusValueRankMon.forEach(it ->{
            JSONObject data = (JSONObject) it;
            double ratio = 0;
            if (data.getDoubleValue("CZ") != 0) {
                ratio = Arith.div( data.getDoubleValue("CZ"),data.getDoubleValue("SUMTOTAL"), 4);
                ratio = Arith.mul(ratio, 100); //百分比
            }
            data.put("ratio", ratio + "%");
        });
        return empBusValueRankMon;
    }


    /**
     * app获取人员产值排名（日）
     * @return
     */
    public JSONArray getEmpTcRank(SimpleRequest simpleRequest){
        JSONObject request = simpleRequest.getJO();

        if(!request.containsKey("DEPT_ID") || StringUtils.isEmpty(request.getString("DEPT_ID")))
            throw new RuntimeException("获取预估产值/提成,门店编码不能为空!!!");
        if(!request.containsKey("TJRQ") || StringUtils.isEmpty(request.getString("TJRQ")))
            throw new RuntimeException("获取预估产值/提成,日期不能为空!!!");
        //查看人员预估提成排名
        JSONArray empTcRank = tcDao.getEmpTcRank(request);
        empTcRank.forEach(it ->{
            JSONObject data = (JSONObject) it;
            double ratio = 0;
            if (data.getDoubleValue("TC") != 0) {
                ratio = Arith.div( data.getDoubleValue("TC"),data.getDoubleValue("SUMTOTAL"), 4);
                ratio = Arith.mul(ratio, 100); //百分比
            }
            data.put("ratio", ratio + "%");
        });
        return empTcRank;
    }

    /**
     * app获取人员产值排名（月）
     * @return
     */
    public JSONArray getEmpTcRankMon(SimpleRequest simpleRequest){
        JSONObject request = simpleRequest.getJO();

        if(!request.containsKey("DEPT_ID") || StringUtils.isEmpty(request.getString("DEPT_ID")))
            throw new RuntimeException("获取预估产值/提成,门店编码不能为空!!!");
        if(!request.containsKey("TJRQ") || StringUtils.isEmpty(request.getString("TJRQ")))
            throw new RuntimeException("获取预估产值/提成,日期不能为空!!!");
        String StrTjrq = request.getString("TJRQ");
        Date tjrq = DateUtil.parse(StrTjrq);
        Date last = DateUtil.getMonthLastDay(tjrq);
        Date first = DateUtil.getMonthFirstDay(tjrq);
        request.put("TJRQ",DateUtil.format(first,DateUtil.SHOW_DATE_FORMAT));
        request.put("TJRQEND",DateUtil.format(last,DateUtil.SHOW_DATE_FORMAT));
        //查看人员预估产值排名
        JSONArray empTcRankMon = tcDao.getEmpTcRankMon(request);

        empTcRankMon.forEach(it ->{
            JSONObject data = (JSONObject) it;
            double ratio = 0;
            if (data.getDoubleValue("TC") != 0) {
                ratio = Arith.div( data.getDoubleValue("TC"),data.getDoubleValue("SUMTOTAL"), 4);
                ratio = Arith.mul(ratio, 100); //百分比
            }
            data.put("ratio", ratio + "%");
        });

        return empTcRankMon;
    }/**
     * app获取人员产值排名（周）
     * @return
     */
    public JSONArray getEmpTcRankWeek(SimpleRequest simpleRequest){
        JSONObject request = simpleRequest.getJO();

        if(!request.containsKey("DEPT_ID") || StringUtils.isEmpty(request.getString("DEPT_ID")))
            throw new RuntimeException("获取预估产值/提成,门店编码不能为空!!!");
        if(!request.containsKey("TJRQ_S") || StringUtils.isEmpty(request.getString("TJRQ_S")))
            throw new RuntimeException("获取预估产值/提成,日期不能为空!!!");
        if(!request.containsKey("TJRQ_E") || StringUtils.isEmpty(request.getString("TJRQ_E")))
            throw new RuntimeException("获取预估产值/提成,日期不能为空!!!");
        String StrTjrq_s = request.getString("TJRQ_S");
        String StrTjrq_e = request.getString("TJRQ_E");
        Date tjrq_s = DateUtil.parse(StrTjrq_s);
        Date tjrq_e = DateUtil.parse(StrTjrq_e);
//        Date last = DateUtil.getMonthLastDay(tjrq);
//        Date first = DateUtil.getMonthFirstDay(tjrq);
        request.put("TJRQ",DateUtil.format(tjrq_s,DateUtil.SHOW_DATE_FORMAT));
        request.put("TJRQEND",DateUtil.format(tjrq_e,DateUtil.SHOW_DATE_FORMAT));
        //查看人员预估产值排名
        JSONArray empTcRankMon = tcDao.getEmpTcRankMon(request);

        empTcRankMon.forEach(it ->{
            JSONObject data = (JSONObject) it;
            double ratio = 0;
            if (data.getDoubleValue("TC") != 0) {
                ratio = Arith.div( data.getDoubleValue("TC"),data.getDoubleValue("SUMTOTAL"), 4);
                ratio = Arith.mul(ratio, 100); //百分比
            }
            data.put("ratio", ratio + "%");
        });

        return empTcRankMon;
    }

    public Map getKDTCtoApp(SimpleRequest request){
        JSONObject jsonObject = request.getJO();
        if(!tcOutboxRepository.findByOrderId(jsonObject.getString("orderId")).isEmpty()) return new HashMap();
        if(StringUtils.isEmpty(jsonObject.getString("deptId"))) throw new RuntimeException("传入部门错误");
            Dept dept = deptRepository.findOne(jsonObject.getString("deptId"));
        jsonObject.put("companyId",dept.getCompany().getId());
        tcOutboxRepository.insertKDTC(jsonObject.getString("orderId"),jsonObject.getString("plateLicense"),jsonObject.getString("companyId")
                ,jsonObject.getString("deptId"),jsonObject.getString("billMan"),Double.parseDouble(jsonObject.getString("tcAmt"))
                ,jsonObject.getString("source"),jsonObject.getString("BillingType"),jsonObject.getString("completionMethod"),jsonObject.getString("childNodeName"));
        return tcOutboxRepository.findByOrderId(jsonObject.getString("orderId"));
    }

    private void invokeTC(String aggregateType,String aggregateId){
        if (aggregateType.equals("RetailOrder")) {
            this.invoke("tc.employeeCommissionService.execXSTC", MapUtil.mapper("ID", aggregateId));

            this.invoke("tc.employeeCommissionService.execNKTC", MapUtil.mapper("ID", aggregateId));

            this.invoke("tc.employeeCommissionService.execDJSGTC", MapUtil.mapper("ID", aggregateId));

            this.invoke("tc.employeeCommissionService.execYYKDTC", MapUtil.mapper(
                    "ID", aggregateId));

            this.invoke("tc.employeeCommissionService.execDKTCDSWC", MapUtil.mapper(
                    "ID", aggregateId));

            this.invoke("tc.employeeCommissionService.execDSFWTC", MapUtil.mapper(
                    "ID", aggregateId));

            this.invoke("tc.employeeCommissionService.execDSGZTC", MapUtil.mapper(
                    "ID", aggregateId));

        } else if (aggregateType.equals("SaleOrder")) {

            this.invoke("tc.employeeCommissionService.execFXXSTC", MapUtil.mapper(
                    "ID", aggregateId));

            this.invoke("tc.employeeCommissionService.execFXDJSGTC", MapUtil.mapper(
                    "ID", aggregateId));

        } else if (aggregateType.equals("InnerPickDeliveryUpCar")) {

            this.invoke("tc.employeeCommissionService.execNXKDTC", MapUtil.mapper(
                    "ID", aggregateId));

            this.invoke("tc.employeeCommissionService.execJSCTC", MapUtil.mapper(
                    "ID", aggregateId));

        } else if (aggregateType.equals("PolicyInformation")) {

            this.invoke("tc.employeeCommissionService.execCXTC", MapUtil.mapper(
                    "ID", aggregateId));

        } else if (aggregateType.equals("SettleExpense")) {

            this.invoke("tc.employeeCommissionService.execDSXSTC", MapUtil.mapper(
                    "ID", aggregateId));

        } else if (aggregateType.equals("ClaimWorkOrder")) {
            this.invoke("tc.employeeCommissionService.execDKTCWCDK", MapUtil.mapper(
                    "ID", aggregateId));
        } else if (aggregateType.equals("ServicePlan")) {
            this.invoke("tc.employeeCommissionService.execDJSGTCNX", MapUtil.mapper(
                    "ID", aggregateId));
        }
    }


}
